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