日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【APUE】文件 I/O 操作

發布時間:2025/6/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【APUE】文件 I/O 操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


博客地址 :?http://blog.csdn.net/shulianghan/article/details/46980271






一. 文件打開關閉操作相關函數介紹



1. open 函數



(1) open 函數簡介


open 函數解析 :?

-- 函數定義 :?

#include <fcntl.h>intopen(const char *path, int oflag, ...);


-- 函數作用 : 打開或者創建一個文件;

-- 返回值 : 打開文件成功, 返回文件描述符; 如果失敗, 返回 -1; 返回的文件描述符是最小的未用描述符值



(2) open 函數參數簡介


參數解析 :?

--?const char *path : 要打開或者創建的文件名;

--?int oflag : 函數選項, 可以是多個常量進行 "或" 運算;

-- 第三參數 : 對于打開文件來說是用不到第三參數的, 如果需要創建文件, 則需要指定第三參數;


int oflag 參數必選常量解析 : 下面的三個常量必須只能且只能指定一個;

-- O_RDONLY : 打開的文件只能讀取, 沒有寫權限;

-- O_WRONLY : 打開的文件只能寫入, 沒有讀權限;

-- O_RDWR : 打開的文件既能讀取, 也能寫入, 有雙權限;


int oflag 參數可選常量解析 :?

-- O_APPEND : 每次寫入都追加到文件末尾;

-- O_CREATE : 如果文件不存在, 就創建, 如果有這個參數, 就需要使用第三個參數來指定創建文件時的參數;

-- O_EXCL : 指定該參數, 同時指定 O_CREATE, 文件如果存在就會報錯;

-- O_TRUNC : 如果文件存在, 并且有寫權限的前提下, 打開時會將其內容清空, 從新寫入;

-- O_NOCTTY : 如果第一個參數文件路徑指向一個終端設備, 不能將該設備作為進程的控制終端;

-- O_NONBLOCK : 如果文件路徑指向一個 FIFO, 特殊文件塊, 字符特殊文件, 同時指定該選項, 文件的IO操作設置為非阻塞模式;


int oflag 同步參數可選常量解析?:?

-- O_DSYNC : 每次 write 操作之前等待 IO 完成, 如果寫操作不影響讀取剛寫入的數據, 則不等待文件屬性被更新;

-- O_RSYNC : 讀操作時等待, 直到所有的寫操作都完成;

-- O_SYNC : 每次寫都要等待物理 IO 操作完成, 包括 write 引起的文件屬性更新; 即 數據和屬性同步更新;



2. create 函數



(1) create 函數簡介


create 函數簡介 :?

-- 函數定義 :?

#include <fcntl.h>intcreat(const char *path, mode_t mode); -- 返回值 : 返回只寫打開的文件描述符, 出錯返回 -1;

-- 等效函數 : open(path_name, O_WRONLY | O_CREATE | O_TRUNC, mode);

-- mode_t mode 參數 : 指定文件的所有者;


(2) create 函數局限性


create 局限性 :?

-- 只寫 : create 函數只能以只寫方式打開創建的文件;

-- 讀取新文件方法 : 先 create 創建只寫文件, 再調用 close 函數, 再調用 open 方法打開文件讀取文件;

-- 創建只讀文件 : open(path_name, O_RDWR | O_CREATE | O_TRUNC, mode);



3. close 函數



函數簡介 :?

-- 函數定義 :?

#include <unistd.h>intclose(int fildes);-- 作用 : 關閉文件, 并釋放 進程 加在該文件上得所有 記錄鎖;

-- 關于進程 : 進程終止時, 內核會自動關閉該進程中打開的所有文件, 很多情況下都會使用關閉進程隱式關閉文件;



二. 文件偏移操作相關函數介紹



1. lseek 函數



(1) lseek 函數簡介


lseek 函數簡介 :?

-- 函數定義 :?

#include <unistd.h>off_tlseek(int fildes, off_t offset, int whence);

-- 作用 : 顯式的為一個打開的文件設置偏移量;

-- 返回值 : 如果設置偏移量成功, 返回新的偏移量;


(2) 文件偏移量簡介


文件偏移量 : ?

-- 當前文件偏移量 : 每個打開的文件都有一個當前文件偏移量, 非負整數, 從開始處計算的字節數; 讀寫操作都是從當前文件偏移處開始, 讀寫會使當前文件偏移量增加 讀寫的字節數;

-- 默認偏移量 : 打開一個文件時默認 當前文件偏移量 是0, 除非指定 O_APPEND 選項;

-- 偏移量的值 : 普通文件偏移量必須是非負整數; 對于某些設備文件允許存在負數偏移量, 因此判斷是否可 lseek 時, 要判斷返回的文件偏移量是否 == -1;


(3) int where 參數簡介


where 參數簡介 :?

-- SEEK_SET : 將文件偏移量設置為 0 + offset;

-- SEEK_CUR : 將文件偏移量設置為 當前位移 + offset;

-- SEEK_END : 將文件偏移量設置為 文件長度 + offset;


(4) lseek 源碼示例


源碼示例 :?

/*************************************************************************> File Name: fun_lseek.c> Author: octopus> Mail: octopus_truth.163.com > Created Time: 三 7/22 07:46:59 2015************************************************************************/#include<stdio.h> #include<unistd.h> #include<stdlib.h>int main(int argc, char * argv[]) {/** 設置標準輸入文件的 "當前文件偏移量", * 設置為當前的位置 + 0;*/if(lseek(STDIN_FILENO, 0, SEEK_CUR) == -1)printf("lseek 結果 -1, 該文件不能lseek\n");elseprintf("該文件可以執行 lseek 方法\n");exit(0); }
編譯執行 :?

localhost:file octopus$ gcc fun_lseek.c localhost:file octopus$ ./a.out 該文件可以執行 lseek 方法

(5) 文件空洞


文件空洞形成 :?

-- 文件偏移量作用 : 文件偏移量是記錄在內核中, 不引起 IO 操作, 這個偏移量主要用于執行下一次的 IO 操作;

-- 空洞形成 : 如果文件偏移量大于當前文件長度, 下一次寫操作會直接加長文件, 并在中間形成一個 "文件空洞";

-- 磁盤占用情況 : 文件空洞是不占用磁盤存儲區的, 寫入數據超出文件長度時, 新寫入的數據會重新分配磁盤塊, 之間的一段文件空洞不會占用磁盤空間;



三. 文件讀寫操作相關函數介紹



1. read 函數



函數簡介 :?

-- 函數內容 :?

#include <sys/types.h>#include <sys/uio.h>#include <unistd.h>ssize_tread(int fildes, void *buf, size_t nbyte);-- 作用 : 從 fildes 代表的文件中, 讀取 nbyte 個函數到 buf 緩沖區中, 讀取到得字節數可能少于 nbyte;

-- 返回值 : 如果 read 操作成功, 返回讀取到得字節數, 如果失敗, 返回 -1;



2. write 函數



函數簡介 :?

-- 函數內容 :?

#include <unistd.h>ssize_twrite(int fildes, const void *buf, size_t nbyte);


-- 函數作用 : 將 buf 字符串的前 nbyte 個字節數據寫入 files 文件標示符 代表的文件中;

-- 返回值 : 若成功, 返回已寫的字節數, 如果失敗返回 -1;



3. write read 函數示例



源碼示例 :?

-- 源碼 :?

/*************************************************************************> File Name: fun_read_write.c> Author: Han Shuliang> Mail: octopus_truth@163.com> Created Time: 五 7/29 15:00:18 2016************************************************************************/ #include <stdio.h> #include <unistd.h>#define SIZE 1024int main(int argc, char * argv[]) {int n;char buf[SIZE];//讀取標準輸入流中的數據到 buf 字節數組中while ((n = read(STDIN_FILENO, buf, SIZE)) > 0)//將 buf 字節數組中的數據寫出到 標準輸出流中if(write(STDOUT_FILENO, buf, n)!= n)printf("寫出內容出錯");if(n < 0)printf("讀取過程出錯");return 0; }

-- 執行結果 :?

bogon:file octopus$ gcc fun_read_write.c bogon:file octopus$ ./a.out Han Shuliang Han ShuliangCSDN CSDN^C bogon:file octopus$


4. 函數綜合示例



/*************************************************************************> File Name: fun_read.c> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 7/27 07:09:36 2015************************************************************************/#include <stdio.h> #include <sys/types.h> // ... read() 頭文件 #include <sys/uio.h> // ... read() 頭文件 #include <unistd.h> // ... read() write() 函數頭文件 #include <stdarg.h> // va_list 可變參數操作頭文件 #include <string.h> // strlen strcat 方法的頭文件 #include <errno.h> // errno 的頭文件 #include <stdlib.h> // exit() 方法的頭文件 #include <fcntl.h> // open() 函數的頭文件#define MAXLINE 4096 #define MAXWORD 20void err_sys(const char *fmt, ...);int main(int argc, char * argv[]) {char *buf = "abcdefg\n";char buf_read[MAXWORD];int fd;int creat_result;int write_size;int close_result;int read_size;//創建一個文件, 使用打開方式, 如果文件不存在, 就重創建并打開if( ( fd = open("file_read_write.file", O_WRONLY | O_CREAT | O_TRUNC) ) == -1)err_sys("創建文件出錯");//向文件中寫出數據if( (write_size = write(fd, buf, strlen(buf))) == -1)err_sys("向文件寫出數據出錯");if( (close_result = close(fd)) == -1)err_sys("關閉文件出錯");if( (fd = open("file_read_write.file", O_RDONLY)) == -1)err_sys("打開文件出錯");//從文件中讀取文件內容if( (read_size = read(fd, buf_read, strlen(buf)) ) == -1)err_sys("讀取文件出錯");if( (close_result = close(fd)) == -1)err_sys("關閉文件出錯");printf("文件中得內容 : %s \n", buf_read); }static void err_doit(int errnoflag, int error, const char* fmt, va_list ap) {char buf[MAXLINE];//將 ap 可變參數使用 fmt 格式, 放置 MAXLINE 個字符到 buf 緩沖中vsnprintf(buf, MAXLINE, fmt, ap);/** 如果需要錯誤信息, 根據錯誤號獲取標準錯誤信息, 將該信息添加到 buf 緩沖中* strlen 作用 : 獲取字符串長度* strerror 作用 : 根據錯誤號獲取錯誤信息*/if(errnoflag)snprintf(buf + strlen(buf), MAXLINE - strlen(buf), ": %s", strerror(errno));//在 buf 字符串后添加換行符號strcat(buf, "\n");//刷新標準輸出流fflush(stdout);//將標準錯誤輸出添加到 buf 緩沖區中fputs(buf, stderr);//刷新所有緩沖區fflush(NULL); }void err_sys(const char *fmt, ...) {va_list ap;va_start(ap, fmt);err_doit(1, errno, fmt, ap);va_end(ap);exit(0); }
執行結果 :?

octopus-2:file octopus$ ls fun_lseek.c fun_lseek_hole.c fun_read_write.c octopus-2:file octopus$ gcc fun_read_write.c octopus-2:file octopus$ sudo ./a.out Password: 文件中得內容 : abcdefgoctopus-2:file octopus$ ls a.out file_read_write.file fun_lseek.c fun_lseek_hole.c fun_read_write.c octopus-2:file octopus$



四. 文件讀寫原子操作相關函數介紹




1. pread 函數




pread 函數 :?

-- 1. 函數內容 :

#include <unistd.h> ssize_t pread(int fd, void *buf, size_t count, off_t offset);
?

-- 2. 函數作用 : 讀取文件描述符 fd 對應的文件, 返回讀取到的文件字節個數, 讀取到文件結尾 返回 0, 出現錯誤返回 -1;

-- 3. 函數返回值 : 返回讀取文件的字節數, 讀取到結尾返回 0, 出錯返回 -1;


pread 與 read 方法作用 :?

-- 1. 等價執行流程 : pread 方法等價于 先調用?lseek 方法, ?再調用?read 方法;

-- 2. 與等價流程的區別 : ① 執行 pread 方法時, 先定位 后 讀取 的兩個操作, 不能中斷; ② 文件指針 不更新;



2. pwrite?函數



pwrite?函數 :?

-- 1. 函數內容 :?

#include <unistd.h>ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);

-- 2. 函數作用 : 寫出數據到指定的位置;

-- 3. 函數返回值 : 返回寫出的字節數, 出現錯誤返回 -1;

-- 4. 等價操作 : pwrite 等價于 lseek 和 write 操作;








3. pread 和 pwrite 函數示例




函數示例過程 :?

-- 1. 打開文件, 如果沒有就創建;

-- 2. 寫出 a ~ z 26個子母;

-- 3. 讀取文件?10 ~ 15 個字節;

-- 4. 向第 10 個字節處寫出 "00000" 字符串;


函數示例 :?

-- 代碼 :?

#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h>int main(int argc, char **argv) {printf("main : \n");int file_fd, write_result;char * buffer = "abcdefghigklmnopqrstuvwxyz";file_fd = open("5.pread_write.txt", O_RDWR | O_APPEND | O_CREAT);printf("file_fd = %d\n", file_fd);write_result = write(file_fd, buffer, strlen(buffer));printf("write success, count = %d\n", write_result);return 0; }

.



.




.













.













.












.


博客地址 :?http://blog.csdn.net/shulianghan/article/details/46980271


總結

以上是生活随笔為你收集整理的【APUE】文件 I/O 操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。