用軟件(文件操作基礎(chǔ)1))
一、文件基礎(chǔ)概念1. 文件程序變量、數(shù)組、數(shù)據(jù)結(jié)構(gòu)存放在內(nèi)存文件存儲在外存硬盤。對比項內(nèi)存外存(硬盤/文件)讀寫速度快比內(nèi)存慢數(shù)據(jù)保持程序執(zhí)行結(jié)束、掉電數(shù)據(jù)丟失掉電數(shù)據(jù)不丟失空間/價格空間小價格昂貴空間大相對內(nèi)存價格便宜文件用于長期保存掉電不丟失的數(shù)據(jù)。Linux一切皆文件硬件也通過文件接口給應(yīng)用層操作。2. Linux下文件類型ls -l 文件名可以查看文件信息。示例-rwxrwxr-x 1 linux linux 19856 Aug 14 19:20 a.outLinux一共7種文件類型標志類型說明示例bblock 塊設(shè)備文件存儲類文件硬盤ccharacter 字符設(shè)備文件字符設(shè)備鼠標、鍵盤、顯示器ddirectory 目錄文件文件夾普通文件夾-regular 普通文件普通文件main.c、txt、jpg、可執(zhí)行程序llink 軟連接文件快捷方式符號鏈接—ssocket 套接字文件網(wǎng)絡(luò)編程—ppipe 管道文件進程間通信—普通文件分為二進制文件存儲二進制01序列如a.out、png、mp3ASCII文本文件存儲字符如.c、.h、.txt可用cat、od -c查看3. Linux下文件操作方法標準IOC庫函數(shù)#include stdio.h例如printf、scanf文件IO系統(tǒng)調(diào)用由Linux內(nèi)核提供接口文件操作通用流程打開文件讀寫文件關(guān)閉文件man手冊使用Linux命令man 1 ls系統(tǒng)調(diào)用man 2 open庫函數(shù)man 3 fopen二、標準IO文件流讀寫過程中的字節(jié)流標準IO操作面向FILE*文件流指針。系統(tǒng)默認預先打開三個流文件流對應(yīng)設(shè)備說明stdin鍵盤標準輸入流stdout終端顯示屏標準輸出流stderr終端顯示屏標準錯誤流1. fopen 打開文件FILE *fopen(const char *pathname, const char *mode);參數(shù)pathname文件路徑名稱mode打開模式mode含義r只讀文件必須存在r讀寫文件必須存在w只寫不存在創(chuàng)建存在清空原有內(nèi)容w讀寫不存在創(chuàng)建存在清空原有內(nèi)容a追加只寫不存在創(chuàng)建寫在文件末尾a讀寫讀從開頭寫向末尾追加返回成功返回FILE*失敗返回NULL。2. fclose 關(guān)閉文件int fclose(FILE *stream);成功返回0失敗返回EOF(-1)。注意文件用完必須關(guān)閉否則產(chǎn)生文件描述符泄露。3. fputc 寫入單個字符int fputc(int c, FILE *stream);putchar(a)等價于fputc(a,stdout)。 返回成功字符失敗返回EOF。4. fgetc 讀取單個字符int fgetc(FILE *stream);讀到文件末尾/出錯返回EOF。fgetcfputc實現(xiàn)文件拷貝命令行傳參argc/argv#include stdio.h int main(int argc, const char *argv[]) { if (argc 3) { printf(Usage: ./a.out srcfile dstfile\n); return -1; } FILE *fpsrc fopen(argv[1], r); FILE *fpdst fopen(argv[2], w); if (NULL fpsrc || NULL fpdst) { printf(fopen error\n); return -1; } int ret 0; while (1) { ret fgetc(fpsrc); if (EOF ret) { break; } fputc(ret, fpdst); } fclose(fpsrc); fclose(fpdst); return 0; }5. fputs 寫字符串int fputs(const char *s, FILE *stream);將字符串寫入文件不會寫入\0成功返回0失敗返回EOF。6. fgets 讀取一行char *fgets(char *s, int size, FILE *stream);最多讀取size?1字節(jié)末尾自動補\0讀到換行會保存換行符。gets不安全不推薦使用scanf遇到空格、tab、換行停止讀取。fgetsfputs實現(xiàn)文件拷貝函數(shù)int file_cp(const char *srcfile, const char *dstfile) { FILE *fpsrc fopen(srcfile, r); FILE *fpdst fopen(dstfile, w); if (NULL fpsrc || NULL fpdst) { printf(fopen error\n); return -1; } char buff[1024] {0}; while (NULL ! fgets(buff, sizeof(buff), fpsrc)) { fputs(buff, fpdst); } fclose(fpsrc); fclose(fpdst); return 0; }fgets/fputs適合文本文件不適合二進制文件。7. fwrite 塊寫size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);向文件寫入nmemb個、每個大小size字節(jié)的數(shù)據(jù)單元返回成功寫入的單元個數(shù)。8. fread 塊讀size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);從文件讀取nmemb個單元到ptr內(nèi)存返回實際讀到的單元數(shù)量。9. 文件流定位fseek重定位讀寫位置int fseek(FILE *stream, long offset, int whence);SEEK_SET從文件起始位置偏移SEEK_CUR從當前位置偏移SEEK_END從文件末尾偏移ftell獲取當前距離文件開頭字節(jié)偏移long ftell(FILE *stream);rewind將文件流直接回到文件開頭void rewind(FILE *stream);獲取文件大小示例fseek(fp, 0, SEEK_END); len ftell(fp); rewind(fp);三、時間相關(guān)函數(shù)頭文件#include time.h1. time 獲取時間戳秒數(shù)time_t time(time_t *tloc);獲取從1970?01?01 00:00:00到當前的秒數(shù)。2. ctime 將時間戳轉(zhuǎn)為字符串時間char *ctime(const time_t *timep);3. localtime 將時間戳轉(zhuǎn)為tm日歷結(jié)構(gòu)體struct tm *localtime(const time_t *timep);struct tm結(jié)構(gòu)體成員struct tm { int tm_sec; /* 秒 0?60 */ int tm_min; /* 分 0?59 */ int tm_hour; /* 時 0?23 */ int tm_mday; /* 日期 1?31 */ int tm_mon; /* 月份 0?11 */ int tm_year; /* 年份實際tm_year1900 */ int tm_wday; /* 星期 0?6周日0 */ int tm_yday; /* 一年中的第幾天 */ int tm_isdst; /* 夏令時 */ };