成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

學習如何用 C 語言來進行文件輸入輸出操作

開發 后端
如果你打算學習 C 語言的輸入、輸出,可以從 stdio.h 包含文件開始。正如你從其名字中猜到的,該文件定義了所有的標準(“std”)的輸入和輸出(“io”)函數。

[[390686]]

理解 I/O 有助于提升你的效率。

如果你打算學習 C 語言的輸入、輸出,可以從 stdio.h 包含文件開始。正如你從其名字中猜到的,該文件定義了所有的標準(“std”)的輸入和輸出(“io”)函數。

大多數人學習的第一個 stdio.h 的函數是打印格式化輸出的 printf 函數?;蛘呤怯脕泶蛴∫粋€字符串的 puts 函數。這些函數非常有用,可以將信息打印給用戶,但是如果你想做更多的事情,則需要了解其他函數。

你可以通過編寫一個常見 Linux 命令的副本來了解其中一些功能和方法。cp 命令主要用于復制文件。如果你查看 cp 的幫助手冊,可以看到 cp 命令支持非常多的參數和選項。但最簡單的功能,就是復制文件:

  1. cp infile outfile

你只需使用一些讀寫文件的基本函數,就可以用 C 語言來自己實現 cp 命令。

一次讀寫一個字符

你可以使用 fgetc 和 fputc 函數輕松地進行輸入輸出。這些函數一次只讀寫一個字符。該用法被定義在 stdio.h,并且這也很淺顯易懂:fgetc 是從文件中讀取一個字符,fputc 是將一個字符保存到文件中。

  1. int fgetc(FILE *stream);
  2. int fputc(int c, FILE *stream);

編寫 cp 命令需要訪問文件。在 C 語言中,你使用 fopen 函數打開一個文件,該函數需要兩個參數:文件名和打開文件的模式。模式通常是從文件讀?。?code>r)或向文件寫入(w)。打開文件的方式也有其他選項,但是對于本教程而言,僅關注于讀寫操作。

因此,將一個文件復制到另一個文件就變成了打開源文件和目標文件,接著,不斷從第一個文件讀取字符,然后將該字符寫入第二個文件。fgetc 函數返回從輸入文件中讀取的單個字符,或者當文件完成后返回文件結束標記(EOF)。一旦讀取到 EOF,你就完成了復制操作,就可以關閉兩個文件。該代碼如下所示:

  1. do {
  2. ch = fgetc(infile);
  3. if (ch != EOF) {
  4. fputc(ch, outfile);
  5. }
  6. } while (ch != EOF);

你可以使用此循環編寫自己的 cp 程序,以使用 fgetc 和 fputc 函數一次讀寫一個字符。cp.c 源代碼如下所示:

  1. #include <stdio.h>
  2.  
  3. int
  4. main(int argc, char **argv)
  5. {
  6. FILE *infile;
  7. FILE *outfile;
  8. int ch;
  9.  
  10. /* parse the command line */
  11.  
  12. /* usage: cp infile outfile */
  13.  
  14. if (argc != 3) {
  15. fprintf(stderr, "Incorrect usage\n");
  16. fprintf(stderr, "Usage: cp infile outfile\n");
  17. return 1;
  18. }
  19.  
  20. /* open the input file */
  21.  
  22. infile = fopen(argv[1], "r");
  23. if (infile == NULL) {
  24. fprintf(stderr, "Cannot open file for reading: %s\n", argv[1]);
  25. return 2;
  26. }
  27.  
  28. /* open the output file */
  29.  
  30. outfile = fopen(argv[2], "w");
  31. if (outfile == NULL) {
  32. fprintf(stderr, "Cannot open file for writing: %s\n", argv[2]);
  33. fclose(infile);
  34. return 3;
  35. }
  36.  
  37. /* copy one file to the other */
  38.  
  39. /* use fgetc and fputc */
  40.  
  41. do {
  42. ch = fgetc(infile);
  43. if (ch != EOF) {
  44. fputc(ch, outfile);
  45. }
  46. } while (ch != EOF);
  47.  
  48. /* done */
  49.  
  50. fclose(infile);
  51. fclose(outfile);
  52.  
  53. return 0;
  54. }

你可以使用 gcc 來將 cp.c 文件編譯成一個可執行文件:

  1. $ gcc -Wall -o cp cp.c

-o cp 選項告訴編譯器將編譯后的程序保存到 cp 文件中。-Wall 選項告訴編譯器提示所有可能的警告,如果你沒有看到任何警告,則表示一切正常。

讀寫數據塊

通過每次讀寫一個字符來實現自己的 cp 命令可以完成這項工作,但這并不是很快。在復制“日常”文件(例如文檔和文本文件)時,你可能不會注意到,但是在復制大型文件或通過網絡復制文件時,你才會注意到差異。每次處理一個字符需要大量的開銷。

實現此 cp 命令的一種更好的方法是,讀取一塊的輸入數據到內存中(稱為緩存),然后將該數據集合寫入到第二個文件。這樣做的速度要快得多,因為程序可以一次讀取更多的數據,這就就減少了從文件中“讀取”的次數。

你可以使用 fread 函數將文件讀入一個變量中。這個函數有幾個參數:將數據讀入的數組或內存緩沖區的指針(ptr),要讀取的最小對象的大?。?code>size),要讀取對象的個數(nmemb),以及要讀取的文件(stream):

  1. size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

不同的選項為更高級的文件輸入和輸出(例如,讀取和寫入具有特定數據結構的文件)提供了很大的靈活性。但是,在從一個文件讀取數據并將數據寫入另一個文件的簡單情況下,可以使用一個由字符數組組成的緩沖區。

你可以使用 fwrite 函數將緩沖區中的數據寫入到另一個文件。這使用了與 fread 函數有相似的一組選項:要從中讀取數據的數組或內存緩沖區的指針,要讀取的最小對象的大小,要讀取對象的個數以及要寫入的文件。

  1. size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

如果程序將文件讀入緩沖區,然后將該緩沖區寫入另一個文件,則數組(ptr)可以是固定大小的數組。例如,你可以使用長度為 200 個字符的字符數組作為緩沖區。

在該假設下,你需要更改 cp 程序中的循環,以將數據從文件讀取到緩沖區中,然后將該緩沖區寫入另一個文件中:

  1. while (!feof(infile)) {
  2. buffer_length = fread(buffer, sizeof(char), 200, infile);
  3. fwrite(buffer, sizeof(char), buffer_length, outfile);
  4. }

這是更新后的 cp 程序的完整源代碼,該程序現在使用緩沖區讀取和寫入數據:

  1. #include <stdio.h>
  2.  
  3. int
  4. main(int argc, char **argv)
  5. {
  6. FILE *infile;
  7. FILE *outfile;
  8. char buffer[200];
  9. size_t buffer_length;
  10.  
  11. /* parse the command line */
  12.  
  13. /* usage: cp infile outfile */
  14.  
  15. if (argc != 3) {
  16. fprintf(stderr, "Incorrect usage\n");
  17. fprintf(stderr, "Usage: cp infile outfile\n");
  18. return 1;
  19. }
  20.  
  21. /* open the input file */
  22.  
  23. infile = fopen(argv[1], "r");
  24. if (infile == NULL) {
  25. fprintf(stderr, "Cannot open file for reading: %s\n", argv[1]);
  26. return 2;
  27. }
  28.  
  29. /* open the output file */
  30.  
  31. outfile = fopen(argv[2], "w");
  32. if (outfile == NULL) {
  33. fprintf(stderr, "Cannot open file for writing: %s\n", argv[2]);
  34. fclose(infile);
  35. return 3;
  36. }
  37.  
  38. /* copy one file to the other */
  39.  
  40. /* use fread and fwrite */
  41.  
  42. while (!feof(infile)) {
  43. buffer_length = fread(buffer, sizeof(char), 200, infile);
  44. fwrite(buffer, sizeof(char), buffer_length, outfile);
  45. }
  46.  
  47. /* done */
  48.  
  49. fclose(infile);
  50. fclose(outfile);
  51.  
  52. return 0;
  53. }

由于你想將此程序與其他程序進行比較,因此請將此源代碼另存為 cp2.c。你可以使用 gcc 編譯程序:

  1. $ gcc -Wall -o cp2 cp2.c

和之前一樣,-o cp2 選項告訴編譯器將編譯后的程序保存到 cp2 程序文件中。-Wall 選項告訴編譯器打開所有警告。如果你沒有看到任何警告,則表示一切正常。

是的,這真的更快了

使用緩沖區讀取和寫入數據是實現此版本 cp 程序更好的方法。由于它可以一次將文件的多個數據讀取到內存中,因此該程序不需要頻繁讀取數據。在小文件中,你可能沒有注意到使用這兩種方案的區別,但是如果你需要復制大文件,或者在較慢的介質(例如通過網絡連接)上復制數據時,會發現明顯的差距。

我使用 Linux time 命令進行了比較。此命令可以運行另一個程序,然后告訴你該程序花費了多長時間。對于我的測試,我希望了解所花費時間的差距,因此我復制了系統上的 628 MB CD-ROM 鏡像文件。

我首先使用標準的 Linux 的 cp 命令復制了映像文件,以查看所需多長時間。一開始通過運行 Linux 的 cp 命令,同時我還避免使用 Linux 內置的文件緩存系統,使其不會給程序帶來誤導性能提升的可能性。使用 Linux cp 進行的測試,總計花費不到一秒鐘的時間:

  1. $ time cp FD13LIVE.iso tmpfile
  2.  
  3. real 0m0.040s
  4. user 0m0.001s
  5. sys 0m0.003s

運行我自己實現的 cp 命令版本,復制同一文件要花費更長的時間。每次讀寫一個字符則花了將近五秒鐘來復制文件:

  1. $ time ./cp FD13LIVE.iso tmpfile
  2.  
  3. real 0m4.823s
  4. user 0m4.100s
  5. sys 0m0.571s

從輸入讀取數據到緩沖區,然后將該緩沖區寫入輸出文件則要快得多。使用此方法復制文件花不到一秒鐘:

  1. $ time ./cp2 FD13LIVE.iso tmpfile
  2.  
  3. real 0m0.944s
  4. user 0m0.224s
  5. sys 0m0.608s

我演示的 cp 程序使用了 200 個字符大小的緩沖區。我確信如果一次將更多文件數據讀入內存,該程序將運行得更快。但是,通過這種比較,即使只有 200 個字符的緩沖區,你也已經看到了性能上的巨大差異。 

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2024-11-20 10:00:00

Python文件讀寫

2021-04-12 15:34:33

C語言printfscanf

2009-12-17 11:36:55

Ruby輸入輸出

2010-02-06 14:28:38

C++標準輸入輸出

2020-01-10 17:45:06

Git共享文件開源

2010-02-03 15:35:00

C++輸入輸出漢字

2016-11-16 15:05:42

情感分析

2020-09-04 11:02:47

Java技巧參數

2011-11-28 09:25:36

Java輸入輸出

2021-05-07 20:01:23

IO輸入輸出

2011-09-01 18:54:29

WifiGoodReader

2018-03-27 13:33:48

百度

2016-12-14 09:32:49

FileChanne文件復制

2021-04-04 08:00:39

C++編程語言軟件開發

2020-09-24 16:05:44

C語言sqlite3函數

2014-09-04 11:39:43

Linux

2011-07-11 11:05:09

Windows控制臺

2009-12-23 10:57:20

nohup命令

2023-10-30 08:53:36

Python輸入輸出

2010-03-12 19:29:15

python svn腳
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 岛国av在线免费观看 | 成人一级片在线观看 | 免费观看一级毛片 | 亚洲网在线 | av看看| 精品久久一区 | 亚洲精品一区二区网址 | 日本一区二区在线视频 | 九色91视频| 亚洲一区二区三区视频在线 | 99精品电影 | 欧美日韩国产在线观看 | 亚洲欧美日韩高清 | 美女张开腿露出尿口 | 日本一区二区高清视频 | 欧美一二区 | 成人欧美一区二区 | 国产一区久久 | 午夜在线免费观看视频 | 九九视频网 | 欧洲一区二区三区 | 91色视频在线观看 | 国产成人jvid在线播放 | 综合久久99 | 国产精品国产亚洲精品看不卡15 | 国产目拍亚洲精品99久久精品 | 中文字幕视频在线 | 亚卅毛片 | 伊人狠狠干 | 亚洲欧美一区二区三区国产精品 | 成人夜晚看av| 成人精品国产一区二区4080 | 91免费在线看 | 久草福利 | 久草网址 | 国产激情一区二区三区 | 国产乱码精品一区二区三区av | 久久专区 | 欧美日韩精品中文字幕 | 啪啪免费网站 | 欧美影院 |