做鋼材的網(wǎng)站有哪些網(wǎng)站的網(wǎng)站建設(shè)
文件I/O和標(biāo)準(zhǔn)I/O
什么是文件I/O?什么是標(biāo)準(zhǔn)I/O?
-
文件I/O:文件I/O又稱系統(tǒng)IO,系統(tǒng)調(diào)用,稱之為不帶緩存的IO(unbuffered I/O)。是操作系統(tǒng)提供的API接口函數(shù)。不帶緩存指的是每個(gè)read,write都調(diào)用內(nèi)核中的一個(gè)系統(tǒng)調(diào)用。也就是一般所說(shuō)的低級(jí)I/O——操作系統(tǒng)提供的基本IO服務(wù),與os綁定,特定于linix或unix平臺(tái)。
-
標(biāo)準(zhǔn)I/O:標(biāo)準(zhǔn)I/O是ANSI C建立的一個(gè)標(biāo)準(zhǔn)I/O模型,是一個(gè)標(biāo)準(zhǔn)函數(shù)包和stdio.h頭文件中的定義,具有一定的可移植性。標(biāo)準(zhǔn)I/O庫(kù)處理很多細(xì)節(jié)。例如緩存分配,以優(yōu)化長(zhǎng)度執(zhí)行I/O等。標(biāo)準(zhǔn)的I/O提供了三種類型的緩存。
(1)全緩存:當(dāng)填滿標(biāo)準(zhǔn)I/O緩存后才進(jìn)行實(shí)際的I/O操作。?
(2)行緩存:當(dāng)輸入或輸出中遇到新行符時(shí),標(biāo)準(zhǔn)I/O庫(kù)執(zhí)行I/O操作。?
(3)不帶緩存:stderr就是了。
文件I/O和標(biāo)準(zhǔn)I/O的區(qū)別?
文件I/O?又稱為低級(jí)磁盤(pán)I/O,遵循POSIX相關(guān)標(biāo)準(zhǔn)。任何兼容POSIX標(biāo)準(zhǔn)的操作系統(tǒng)上都支持文件I/O。標(biāo)準(zhǔn)I/O被稱為高級(jí)磁盤(pán)I/O,遵循ANSI C相關(guān)標(biāo)準(zhǔn)。只要開(kāi)發(fā)環(huán)境中有標(biāo)準(zhǔn)I/O庫(kù),標(biāo)準(zhǔn)I/O就可以使用。(Linux 中使用的是GLIBC,它是標(biāo)準(zhǔn)C庫(kù)的超集。不僅包含ANSI C中定義的函數(shù),還包括POSIX標(biāo)準(zhǔn)中定義的函數(shù)。因此,Linux 下既可以使用標(biāo)準(zhǔn)I/O,也可以使用文件I/O)。
通過(guò)文件I/O讀寫(xiě)文件時(shí),每次操作都會(huì)執(zhí)行相關(guān)系統(tǒng)調(diào)用。這樣處理的好處是直接讀寫(xiě)實(shí)際文件,壞處是頻繁的系統(tǒng)調(diào)用會(huì)增加系統(tǒng)開(kāi)銷,標(biāo)準(zhǔn)I/O可以看成是在文件I/O的基礎(chǔ)上封裝了緩沖機(jī)制。先讀寫(xiě)緩沖區(qū),必要時(shí)再訪問(wèn)實(shí)際文件,從而減少了系統(tǒng)調(diào)用的次數(shù)。
文件I/O中用文件描述符表現(xiàn)一個(gè)打開(kāi)的文件,可以訪問(wèn)不同類型的文件如普通文件、設(shè)備文件和管道文件等。而標(biāo)準(zhǔn)I/O中用FILE(流)表示一個(gè)打開(kāi)的文件,通常只用來(lái)訪問(wèn)普通文件。
文件I/O:文件描述符
文件描述符不是指針,與標(biāo)準(zhǔn)IO FILE *fp不同,文件描述符是一個(gè)非負(fù)整數(shù)。?
- 每個(gè)打開(kāi)的文件都對(duì)應(yīng)一個(gè)文件描述符。
- 文件描述符是一個(gè)非負(fù)整數(shù)。
- Linux為程序中每個(gè)打開(kāi)的文件分配一個(gè)文件描述符。
- 文件描述符從0開(kāi)始分配,依次遞增,每個(gè)3-1023的數(shù)字表示一個(gè)文件,數(shù)字不同,表示的文件不同,前三個(gè)被0-標(biāo)準(zhǔn)輸入,1-標(biāo)準(zhǔn)輸出,2-錯(cuò)誤占用。
- 文件IO操作通過(guò)文件描述符來(lái)完成。
文件I/O和標(biāo)準(zhǔn)I/O使用的函數(shù)?
標(biāo)準(zhǔn)I/O | 文件I/O(低級(jí)I/O) | |
打開(kāi) | fopen,freopen,fdopen | open |
關(guān)閉 | fclose | close |
讀 | getc,fgetc,getchar fgets,gets fread | read |
寫(xiě) | putc,fputc,putchar fputs,puts, fwrite | write |
文件I/O打開(kāi)函數(shù):open()
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags); //不能創(chuàng)建文件
int open(const char *pathname, int flags, mode_t mode);
主要功能
open函數(shù)用來(lái)創(chuàng)建或打開(kāi)一個(gè)文件。
返回值
?成功時(shí)返回文件描述符;出錯(cuò)時(shí)返回EOF
- 打開(kāi)文件時(shí)使用兩個(gè)參數(shù),不可創(chuàng)建文件
- 創(chuàng)建文件時(shí)第三個(gè)參數(shù)指定新文件的權(quán)限,(只有在建立新文件時(shí)有效)此外真正建文件時(shí)的權(quán)限會(huì)受到umask 值影響,實(shí)際權(quán)限是mode-umaks
- 可以打開(kāi)設(shè)備文件,但是不能創(chuàng)建設(shè)備文件(創(chuàng)建設(shè)備文件用mknode)
參數(shù)介紹
?與標(biāo)準(zhǔn)I/O的權(quán)限對(duì)照(普通用戶)
標(biāo)準(zhǔn)I/O | 文件I/O |
r | O_RDONLY |
r+ | O_RDWR |
w | O_WRONLY | O_CREAT | O_TRUNC, 0664 |
w+ | O_RDWR | O_CREAT | O_TRUNC, 0664 |
a | O_WRONLY | O_CREAT | O_APPEND, 0664 |
a+ | O_RDWR | O_CREAT | O_APPEND, 0664 |
umask :用來(lái)設(shè)定文件或目錄的初始權(quán)限
文件和目錄的真正初始權(quán)限
文件或目錄的初始權(quán)限(0664) = 文件或目錄的最大默認(rèn)權(quán)限(0666) - umask權(quán)限(0002)
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc, const char *argv[])
{ int fd;fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd < 0) {printf("open file err\n");return 0;}printf("success\n");return 0;
}
文件I/O關(guān)閉函數(shù):close()
#include <unistd.h>int close(int fd);
主要功能
close函數(shù)用來(lái)關(guān)閉一個(gè)文件。
返回值
成功時(shí)返回0;出錯(cuò)時(shí)返回EOF
打開(kāi)和關(guān)閉函數(shù)實(shí)例代碼
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, const char *argv[])
{ int fd;int ret;fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd < 0) {printf("open file err\n");return 0;}printf("success, fd = %d\n", fd);if ((ret = close(fd)) < 0) {printf("close failed\n");}ret = close(fd);printf("close failed\n");return 0;
}
運(yùn)行結(jié)果?
success, fd = 3
close failed
文件I/O讀取函數(shù):read()
#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);
主要功能
?read函數(shù)用來(lái)從文件中讀取數(shù)據(jù)
- 讀到文件末尾時(shí)返回0
- buf是接收數(shù)據(jù)的緩沖區(qū)
- count不應(yīng)超過(guò)buf大小
返回值
成功時(shí)返回實(shí)際讀取的字節(jié)數(shù);出錯(cuò)時(shí)返回EOF?
文件I/O寫(xiě)入函數(shù):write()
#include <unistd.h>ssize_t write(int fd, void *buf, size_t count);
主要功能
write函數(shù)用來(lái)向文件寫(xiě)入數(shù)據(jù)
- buf是發(fā)送數(shù)據(jù)的緩沖區(qū)
- count不應(yīng)超過(guò)buf大小
返回值
成功時(shí)返回實(shí)際寫(xiě)入的字節(jié)數(shù);出錯(cuò)時(shí)返回EOF
文件I/O定位函數(shù):lseek()
#include <unistd.h>off_t lseek(int fd, off_t offset, intt whence);
主要功能
lseek函數(shù)用來(lái)定位文件,參數(shù)offset和參數(shù)whence同fseek完全一樣。參見(jiàn):【嵌入式開(kāi)發(fā)之標(biāo)準(zhǔn)I/O】流的刷新、定位以及格式化輸出、輸入
返回值
成功時(shí)返回當(dāng)前的文件讀寫(xiě)位置;出錯(cuò)時(shí)返回EOF
文件I/O讀取、寫(xiě)入和定位函數(shù)實(shí)例代碼
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(int argc, const char *argv[])
{int fd;int ret;char buf[32] = "hello word";char buf2[32] = {0};//打開(kāi)文件fd = open("test.txt", O_RDWR | O_CREAT | O_APPEND, 0666);if (fd < 0) {printf("open file err\n");return 0;}printf("success, fd = %d\n", fd);//寫(xiě)入數(shù)據(jù)if ((ret = write(fd, buf, strlen(buf))) < 0) {perror("write");goto end;}printf("write count = %d\n", ret);//定位文件到開(kāi)頭lseek(fd, 0, SEEK_SET);//讀取文件if (( ret = read(fd, buf2, 32)) < 0) {perror("read");goto end;}printf("read count = %d\n", ret);buf2[31] = 0;printf("buf2 = %s\n", buf2);end:close(fd);return 0;
}
運(yùn)行結(jié)果
success, fd = 3
write count = 10
read count = 10
buf2 = hello word