Computer Programming 简明教程

Computer Programming - File I/O

Computer Files

计算机文件用于以纯文本、图像数据或任何其他内容之类的数字格式存储数据。可以将计算机文件组织在不同的目录中。文件用于保存数字数据,而目录用于保存文件。

计算机文件可以被视为纸质文件的数字对应物。在编程时,在带有不同扩展名的文本文件中保存源代码,例如,C 编程文件以 .c 扩展名结尾,Java 编程文件以 .java 结尾,Python 文件以 .py 结尾。

File Input/Output

通常,使用文本编辑器(如记事本、MS Word、MS Excel 或 MS Powerpoint 等)创建文件。但是,许多时候,我们也需要使用计算机程序创建文件。我们可以使用计算机程序修改现有文件。

文件输入表示写入文件的数据,文件输出表示从文件中读取的数据。实际上,输入和输出项更与屏幕输入和输出相关。当我们在屏幕上显示结果时,称为输出。同样,如果我们从命令提示符向程序提供一些输入,则称为输入。

现在,记住这一点就足够了:写入文件是文件输入,从文件中读取内容是文件输出。

File Operation Modes

在我们开始使用计算机程序处理任何文件之前,我们需要创建一个新文件(如果它不存在)或打开一个已存在的文件。在这两种情况下,我们都可以在以下模式下打开文件 −

  1. Read-Only Mode − 如果要仅仅读取现有文件且不希望在文件中写入任何进一步内容,那么将以只读模式打开该文件。几乎所有编程语言都提供以只读模式打开文件的语法。

  2. Write-Only Mode − 如果要写入现有文件或新创建的文件,但不想从中读取任何已写入内容,那么将以只写模式打开该文件。所有编程语言都提供以只写模式打开文件的语法。

  3. Read & Write Mode − 如果要读取和写入同一文件,那么将在读写模式下打开文件。

  4. Append Mode − 为写入目的打开文件时,它允许你从文件的开头开始写入;但是,它将覆盖现有内容(如果有)。假设我们不想覆盖任何现有内容,那么我们将在追加模式下打开该文件。追加模式最终是一种写入模式,它允许将内容附加到文件的末尾。几乎所有编程语言都提供以追加模式打开文件的语法。

在随后的章节中,我们将了解如何打开一个新文件、如何写入该文件以及如何在同一文件中读取和追加更多内容。

Opening Files

你可以使用 fopen() 函数创建新文件或打开现有文件。此调用将初始化一个 FILE 类型的对象,该对象包含控制流所需的所有信息。以下是该函数调用的原型,即签名 −

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

在此, filename 是字符串字面量,将使用它来命名文件和访问 mode 可以具有以下值之一 −

Sr.No

Mode & Description

1

r 打开一个现有的文本文件以供读取。

2

w 以可写格式打开文本文件。如果它不存在,则创建一个新文件。在此,你的程序将从文件的开头开始写入内容。

3

a 以追加模式打开文本文件进行写入。如果它不存在,则创建一个新文件。在此,你的程序将开始在现有文件内容中追加内容。

4

r+ 为读取和写入打开一个文本文件。

5

w+ 以读写格式打开文本文件。如果存在,则首先将其截断为零长度;否则,如果不存在,则创建文件。

6

a+ 以读写格式打开文本文件。如果它不存在,则创建一个文件。读取将从开头开始,但只能追加写入。

Closing a File

要关闭文件,请使用 fclose( ) 函数。此函数的原型为 −

 int fclose( FILE *fp );

fclose( ) 函数在成功时返回零,或在关闭文件时出错时返回 EOF 特殊字符。此函数实际上会将缓冲区中仍处于未决状态的任何数据写入至文件,关闭文件并释放用于该文件的所有内存。EOF 是在头文件 stdio.h 中定义的常数。

C 标准库提供了用于逐个字符或以固定长度字符串形式读写文件的各种函数。我们将在下一节中了解其中的一些函数。

Writing a File

下面列出用于将单个字符写入流的最简单的函数 −

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 ,并使用两个不同的函数写入两行。让我们在下一节中读取此文件。

Reading a File

下面列出用于逐个字符读取文本文件的最简单的函数 −

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() 完全读到了第二行。

File I/O in Java

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...

File I/O in Python

以下程序展示了相同的打开新文件、向其中写入一些内容的功能,最后,读取相同的文件 −

# 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...