您好,登錄后才能下訂單哦!
本篇內容主要講解“如何用 C 語言來進行文件輸入輸出操作”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何用 C 語言來進行文件輸入輸出操作”吧!
如果你打算學習 C 語言的輸入、輸出,可以從 stdio.h
包含文件開始。正如你從其名字中猜到的,該文件定義了所有的標準(“std”)的輸入和輸出(“io”)函數。
大多數人學習的第一個 stdio.h
的函數是打印格式化輸出的 printf
函數。或者是用來打印一個字符串的 puts
函數。這些函數非常有用,可以將信息打印給用戶,但是如果你想做更多的事情,則需要了解其他函數。
你可以通過編寫一個常見 Linux 命令的副本來了解其中一些功能和方法。cp
命令主要用于復制文件。如果你查看 cp
的幫助手冊,可以看到 cp
命令支持非常多的參數和選項。但最簡單的功能,就是復制文件:
cp infile outfile
你只需使用一些讀寫文件的基本函數,就可以用 C 語言來自己實現 cp
命令。
你可以使用 fgetc
和 fputc
函數輕松地進行輸入輸出。這些函數一次只讀寫一個字符。該用法被定義在 stdio.h
,并且這也很淺顯易懂:fgetc
是從文件中讀取一個字符,fputc
是將一個字符保存到文件中。
int fgetc(FILE *stream);int fputc(int c, FILE *stream);
編寫 cp
命令需要訪問文件。在 C 語言中,你使用 fopen
函數打開一個文件,該函數需要兩個參數:文件名和打開文件的模式。模式通常是從文件讀取(r
)或向文件寫入(w
)。打開文件的方式也有其他選項,但是對于本教程而言,僅關注于讀寫操作。
因此,將一個文件復制到另一個文件就變成了打開源文件和目標文件,接著,不斷從第一個文件讀取字符,然后將該字符寫入第二個文件。fgetc
函數返回從輸入文件中讀取的單個字符,或者當文件完成后返回文件結束標記(EOF
)。一旦讀取到 EOF
,你就完成了復制操作,就可以關閉兩個文件。該代碼如下所示:
do { ch = fgetc(infile); if (ch != EOF) { fputc(ch, outfile); } } while (ch != EOF);
你可以使用此循環編寫自己的 cp
程序,以使用 fgetc
和 fputc
函數一次讀寫一個字符。cp.c
源代碼如下所示:
#include <stdio.h> intmain(int argc, char **argv){ FILE *infile; FILE *outfile; int ch; /* parse the command line */ /* usage: cp infile outfile */ if (argc != 3) { fprintf(stderr, "Incorrect usage\n"); fprintf(stderr, "Usage: cp infile outfile\n"); return 1; } /* open the input file */ infile = fopen(argv[1], "r"); if (infile == NULL) { fprintf(stderr, "Cannot open file for reading: %s\n", argv[1]); return 2; } /* open the output file */ outfile = fopen(argv[2], "w"); if (outfile == NULL) { fprintf(stderr, "Cannot open file for writing: %s\n", argv[2]); fclose(infile); return 3; } /* copy one file to the other */ /* use fgetc and fputc */ do { ch = fgetc(infile); if (ch != EOF) { fputc(ch, outfile); } } while (ch != EOF); /* done */ fclose(infile); fclose(outfile); return 0;}
你可以使用 gcc
來將 cp.c
文件編譯成一個可執行文件:
$ gcc -Wall -o cp cp.c
-o cp
選項告訴編譯器將編譯后的程序保存到 cp
文件中。-Wall
選項告訴編譯器提示所有可能的警告,如果你沒有看到任何警告,則表示一切正常。
通過每次讀寫一個字符來實現自己的 cp
命令可以完成這項工作,但這并不是很快。在復制“日常”文件(例如文檔和文本文件)時,你可能不會注意到,但是在復制大型文件或通過網絡復制文件時,你才會注意到差異。每次處理一個字符需要大量的開銷。
實現此 cp
命令的一種更好的方法是,讀取一塊的輸入數據到內存中(稱為緩存),然后將該數據集合寫入到第二個文件。這樣做的速度要快得多,因為程序可以一次讀取更多的數據,這就就減少了從文件中“讀取”的次數。
你可以使用 fread
函數將文件讀入一個變量中。這個函數有幾個參數:將數據讀入的數組或內存緩沖區的指針(ptr
),要讀取的最小對象的大小(size
),要讀取對象的個數(nmemb
),以及要讀取的文件(stream
):
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
不同的選項為更高級的文件輸入和輸出(例如,讀取和寫入具有特定數據結構的文件)提供了很大的靈活性。但是,在從一個文件讀取數據并將數據寫入另一個文件的簡單情況下,可以使用一個由字符數組組成的緩沖區。
你可以使用 fwrite
函數將緩沖區中的數據寫入到另一個文件。這使用了與 fread
函數有相似的一組選項:要從中讀取數據的數組或內存緩沖區的指針,要讀取的最小對象的大小,要讀取對象的個數以及要寫入的文件。
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
如果程序將文件讀入緩沖區,然后將該緩沖區寫入另一個文件,則數組(ptr
)可以是固定大小的數組。例如,你可以使用長度為 200 個字符的字符數組作為緩沖區。
在該假設下,你需要更改 cp
程序中的循環,以將數據從文件讀取到緩沖區中,然后將該緩沖區寫入另一個文件中:
while (!feof(infile)) { buffer_length = fread(buffer, sizeof(char), 200, infile); fwrite(buffer, sizeof(char), buffer_length, outfile); }
這是更新后的 cp
程序的完整源代碼,該程序現在使用緩沖區讀取和寫入數據:
#include <stdio.h> intmain(int argc, char **argv){ FILE *infile; FILE *outfile; char buffer[200]; size_t buffer_length; /* parse the command line */ /* usage: cp infile outfile */ if (argc != 3) { fprintf(stderr, "Incorrect usage\n"); fprintf(stderr, "Usage: cp infile outfile\n"); return 1; } /* open the input file */ infile = fopen(argv[1], "r"); if (infile == NULL) { fprintf(stderr, "Cannot open file for reading: %s\n", argv[1]); return 2; } /* open the output file */ outfile = fopen(argv[2], "w"); if (outfile == NULL) { fprintf(stderr, "Cannot open file for writing: %s\n", argv[2]); fclose(infile); return 3; } /* copy one file to the other */ /* use fread and fwrite */ while (!feof(infile)) { buffer_length = fread(buffer, sizeof(char), 200, infile); fwrite(buffer, sizeof(char), buffer_length, outfile); } /* done */ fclose(infile); fclose(outfile); return 0;}
由于你想將此程序與其他程序進行比較,因此請將此源代碼另存為 cp2.c
。你可以使用 gcc
編譯程序:
$ gcc -Wall -o cp2 cp2.c
和之前一樣,-o cp2
選項告訴編譯器將編譯后的程序保存到 cp2
程序文件中。-Wall
選項告訴編譯器打開所有警告。如果你沒有看到任何警告,則表示一切正常。
使用緩沖區讀取和寫入數據是實現此版本 cp
程序更好的方法。由于它可以一次將文件的多個數據讀取到內存中,因此該程序不需要頻繁讀取數據。在小文件中,你可能沒有注意到使用這兩種方案的區別,但是如果你需要復制大文件,或者在較慢的介質(例如通過網絡連接)上復制數據時,會發現明顯的差距。
我使用 Linux time
命令進行了比較。此命令可以運行另一個程序,然后告訴你該程序花費了多長時間。對于我的測試,我希望了解所花費時間的差距,因此我復制了系統上的 628 MB CD-ROM 鏡像文件。
我首先使用標準的 Linux 的 cp
命令復制了映像文件,以查看所需多長時間。一開始通過運行 Linux 的 cp
命令,同時我還避免使用 Linux 內置的文件緩存系統,使其不會給程序帶來誤導性能提升的可能性。使用 Linux cp
進行的測試,總計花費不到一秒鐘的時間:
$ time cp FD13LIVE.iso tmpfile real 0m0.040suser 0m0.001ssys 0m0.003s
運行我自己實現的 cp
命令版本,復制同一文件要花費更長的時間。每次讀寫一個字符則花了將近五秒鐘來復制文件:
$ time ./cp FD13LIVE.iso tmpfile real 0m4.823suser 0m4.100ssys 0m0.571s
從輸入讀取數據到緩沖區,然后將該緩沖區寫入輸出文件則要快得多。使用此方法復制文件花不到一秒鐘:
$ time ./cp2 FD13LIVE.iso tmpfile real 0m0.944suser 0m0.224ssys 0m0.608s
我演示的 cp
程序使用了 200 個字符大小的緩沖區。我確信如果一次將更多文件數據讀入內存,該程序將運行得更快。但是,通過這種比較,即使只有 200 個字符的緩沖區,你也已經看到了性能上的巨大差異。
到此,相信大家對“如何用 C 語言來進行文件輸入輸出操作”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。