計算機程式設計 - 檔案 I/O



計算機檔案

計算機檔案用於以數字格式儲存資料,例如純文字、影像資料或任何其他內容。計算機檔案可以組織在不同的目錄中。檔案用於儲存數字資料,而目錄用於儲存檔案。

計算機檔案可以被認為是紙質文件的數字對應物。在程式設計過程中,您將原始碼儲存在具有不同副檔名的文字檔案中,例如,C 程式設計檔案以.c副檔名結尾,Java 程式設計檔案以.java副檔名結尾,Python 檔案以.py副檔名結尾。

檔案輸入/輸出

通常,您使用文字編輯器(例如記事本、MS Word、MS Excel 或 MS Powerpoint 等)建立檔案。但是,很多時候,我們也需要使用計算機程式建立檔案。我們可以使用計算機程式修改現有檔案。

檔案輸入是指寫入檔案的資料,檔案輸出是指從檔案讀取的資料。實際上,輸入和輸出術語更多地與螢幕輸入和輸出相關。當我們在螢幕上顯示結果時,稱為輸出。類似地,如果我們從命令提示符向程式提供一些輸入,則稱為輸入。

目前,記住寫入檔案是檔案輸入,從檔案讀取內容是檔案輸出就足夠了。

檔案操作模式

在我們開始使用計算機程式處理任何檔案之前,我們需要建立一個新檔案(如果它不存在)或開啟一個已存在的檔案。在任何一種情況下,我們都可以以下列模式開啟檔案:

  • 只讀模式 - 如果您只是要讀取現有檔案,並且不想在檔案中寫入任何其他內容,則您將以只讀模式開啟檔案。幾乎所有程式語言都提供以只讀模式開啟檔案的語法。

  • 只寫模式 - 如果您要寫入現有檔案或新建立的檔案,但不想從該檔案讀取任何寫入的內容,則您將以只寫模式開啟檔案。所有程式語言都提供以只寫模式開啟檔案的語法。

  • 讀寫模式 - 如果您要讀取和寫入同一個檔案,則您將以讀寫模式開啟檔案。

  • 追加模式 - 當您開啟檔案以進行寫入時,它允許您從檔案的開頭開始寫入;但是,它會覆蓋任何現有的內容(如果有)。假設我們不想覆蓋任何現有內容,那麼我們將以追加模式開啟檔案。追加模式最終是一種寫入模式,它允許將內容追加到檔案的末尾。幾乎所有程式語言都提供以追加模式開啟檔案的語法。

在接下來的部分中,我們將學習如何開啟一個新的檔案,如何向其中寫入內容,以及隨後如何讀取和追加更多內容到同一個檔案中。

開啟檔案

您可以使用fopen()函式建立新檔案或開啟現有檔案。此呼叫將初始化型別為FILE的物件,其中包含控制流所需的所有資訊。以下是此函式呼叫的原型,即簽名:

FILE *fopen( const char * filename, const char * mode );

這裡,filename是字串文字,您將使用它來命名您的檔案,並且access mode可以具有以下值之一:

序號 模式及描述
1

r

以讀取目的開啟現有文字檔案。

2

w

開啟文字檔案以進行寫入。如果它不存在,則建立一個新檔案。在這裡,您的程式將從檔案的開頭開始寫入內容。

3

a

以追加模式開啟文字檔案以進行寫入。如果它不存在,則建立一個新檔案。在這裡,您的程式將開始將內容追加到現有檔案內容中。

4

r+

開啟文字檔案以進行讀取和寫入。

5

w+

開啟文字檔案以進行讀取和寫入。如果檔案存在,則首先將其截斷為零長度;否則,如果檔案不存在,則建立檔案。

6

a+

開啟文字檔案以進行讀取和寫入。如果它不存在,則建立一個檔案。讀取將從開頭開始,但只能追加寫入。

關閉檔案

要關閉檔案,請使用fclose( )函式。此函式的原型為:

 int fclose( FILE *fp );

fclose( )函式在成功時返回零,或者在關閉檔案時出錯時返回EOF特殊字元。此函式實際上將緩衝區中仍掛起的所有資料重新整理到檔案,關閉檔案並釋放用於檔案的任何記憶體。EOF 是在標頭檔案stdio.h中定義的常量。

C 標準庫提供了各種函式來逐字元或以固定長度字串的形式讀取和寫入檔案。讓我們在下一節中瞭解其中的一些。

寫入檔案

以下是將單個字元寫入流的最簡單函式:

int fputc( int c, FILE *fp );

fputc()函式將引數 c 的字元值寫入由fp引用的輸出流。如果成功,它將返回寫入的字元,否則如果發生錯誤,則返回EOF。您可以使用以下函式將以 null 結尾的字串寫入流:

int fputs( const char *s, FILE *fp );

fputs()函式將字串s寫入由 fp 引用的檔案中。如果成功,它將返回非負值,否則在發生任何錯誤時返回EOF。您還可以使用函式int fprintf(FILE *fp,const char *format, ...)將字串寫入檔案。嘗試以下示例:

#include <stdio.h>

int main() {
   FILE *fp;

   fp = fopen("/tmp/test.txt", "w+");
   fprintf(fp, "This is testing for fprintf...\n");
   fputs("This is testing for fputs...\n", fp);
   fclose(fp);
}

當以上程式碼編譯並執行時,它會在/tmp目錄中建立一個名為test.txt的新檔案,並使用兩個不同的函式寫入兩行。讓我們在下一節中讀取此檔案。

讀取檔案

以下是逐字元讀取文字檔案的最簡單函式:

int fgetc( FILE * fp );

fgetc()函式從由fp引用的輸入檔案中讀取一個字元。返回值是讀取的字元;或者在發生任何錯誤時,它返回EOF。以下函式允許您從流中讀取字串:

char *fgets( char *buf, int n, FILE *fp );

fgets()函式最多從由fp引用的輸入流中讀取 n - 1 個字元。它將讀取的字串複製到緩衝區buf中,並附加一個null字元以終止字串。

如果此函式在讀取最大字元數之前遇到換行符'\n'或 EOF,則它只返回讀取的字元,包括換行符。您還可以使用int fscanf(FILE *fp, const char *format, ...)從檔案中讀取字串,但它在遇到第一個空格字元後停止讀取。

#include <stdio.h>

main() {

   FILE *fp;
   char buff[255];

   fp = fopen("/tmp/test.txt", "r");
   fscanf(fp, "%s", buff);
   printf("1 : %s\n", buff );

   fgets(buff, 255, (FILE*)fp);
   printf("2: %s\n", buff );
   
   fgets(buff, 255, (FILE*)fp);
   printf("3: %s\n", buff );
   fclose(fp);
}

當以上程式碼編譯並執行時,它讀取上一節中建立的檔案併產生以下結果:

1 : This
2 : is testing for fprintf...

3 : This is testing for fputs...

讓我們分析一下這裡發生了什麼。首先,fscanf()方法讀取This,因為之後它遇到了一個空格。第二個呼叫是fgets(),它讀取剩餘的行,直到遇到行尾。最後,最後一個呼叫fgets()完整地讀取第二行。

Java 中的檔案 I/O

Java 提供了更豐富的函式集來處理檔案 I/O。有關此主題的更多資訊,我們建議您檢視我們的 Java 教程。

在這裡,我們將看到一個簡單的 Java 程式,它等同於上面解釋的 C 程式。此程式將開啟一個文字檔案,向其中寫入幾行文字,然後關閉檔案。最後,開啟同一個檔案,然後從已建立的檔案中讀取。您可以嘗試執行以下程式以檢視輸出:

import java.io.*;

public class DemoJava {
   public static void main(String []args) throws IOException {
      File file = new File("/tmp/java.txt");
      
      // Create a File
      file.createNewFile();
      
      //  Creates a FileWriter Object using file object
      FileWriter writer = new FileWriter(file); 
      
      // Writes the content to the file
      writer.write("This is testing for Java write...\n");
      writer.write("This is second line...\n");
      
      // Flush the memory and close the file
      writer.flush();
      writer.close();
      
      // Creates a FileReader Object
      FileReader reader = new FileReader(file); 
      char [] a = new char[100];
      
      // Read file content in the array
      reader.read(a);
      System.out.println( a );
      
      // Close the file
      reader.close();
   }
}

當以上程式執行時,它會產生以下結果:

This is testing for Java write...
This is second line...

Python 中的檔案 I/O

以下程式顯示了相同的功能,用於開啟一個新檔案,向其中寫入一些內容,最後讀取同一個檔案:

# Create a new file
fo = open("/tmp/python.txt", "w")

# Writes the content to the file
fo.write( "This is testing for Python write...\n");
fo.write( "This is second line...\n");

# Close the file
fo.close()

# Open existing file
fo = open("/tmp/python.txt", "r")

# Read file content in a variable
str = fo.read(100);
print str

# Close opened file
fo.close()

當以上程式碼執行時,它會產生以下結果:

This is testing for Python write...
This is second line...
廣告