# 文件处理

> 计算机科学 · CIE A-Level
> 来源: https://www.owlsprep.com/zh/study/cie-9618-u11-file-handling/

本模块讲解CIE A-Level计算机科学编程中的核心文件输入输出操作。你将学习如何操作文本和二进制文件、处理常见错误，并在程序中实现持久化数据存储。

**先修:** [过程式编程基础](https://www.owlsprep.com/zh/study/cie-9618-u11-procedural-programming/); [自定义数据类型与记录](https://www.owlsprep.com/zh/study/cie-9618-u10-custom-data-types/)

## 学习目标

- 掌握完整的文件处理生命周期：正确打开、处理、关闭文件
- 区分文本和二进制文件的存储模式
- 实现读取、写入、追加等常见文件操作
- 在伪代码中处理常见的文件访问错误

## 核心文件生命周期：打开、处理、关闭

所有文件操作都遵循标准的三步生命周期：打开文件获取访问权限，执行读取或写入操作，完成后关闭文件。关闭文件对于释放系统资源、确保所有内存中的数据都写入永久存储至关重要。

**文件模式** — 指定打开文件可执行哪些操作，以及如何解释文件内容的设置。

*例:* 常见模式：读取、写入、追加、文本、二进制

**例题:** 编写CIE标准伪代码，以读取模式打开文本文件`scores.txt`，将第一行输出到控制台，然后关闭文件。

1. 声明一个文件句柄引用打开的文件，以及一个字符串变量存储读取的行：
2. ```
DECLARE FileHandle : FILE
DECLARE FirstLine : STRING
```
3. 以只读模式打开文件：
4. ```
OPENFILE "scores.txt" FOR READ AS FileHandle
```
5. 读取第一行，输出它，然后关闭文件：
6. ```
READLINE FileHandle, FirstLine
OUTPUT FirstLine
CLOSEFILE FileHandle
```

> **tip**
>
> CIE阅卷官在编程题中总是会对缺失`CLOSEFILE`语句扣分，所以永远不要忘记这一步。

## 文本文件 vs 二进制文件模式

文本文件将数据存储为人类可读的字符序列，使用ASCII或UTF-8等标准编码。二进制文件直接存储原始二进制数据，更紧凑，并且保留原始数据类型的准确大小。

**例题:** 比较整数123在文本文件和4字节整数二进制文件中的存储方式。

1. 文本文件中：整数被转换为三个独立字符`'1'`, `'2'`, `'3'`，占用3字节存储空间，在文本编辑器中打开会显示可读文本`123`。
2. 二进制文件中：整数123的原始4字节二进制值被直接存储，占用4字节存储空间，在文本编辑器中打开会显示不可读的非打印字符。

> **info**
>
> 理论题经常要求你计算文本文件和二进制文件的大小，所以要记住两种格式的大小差异。

## 常见文件操作

除了基础的单行读取，你通常还需要逐行处理整个文件、向现有文件追加新数据，或搜索特定条目。`EOF`（文件结束）标记用于检测是否已经到达文件内容末尾。

**例题:** 编写伪代码，统计名为`data.txt`的文本文件的总行数。

1. 初始化计数器为0，打开文件以供读取：
2. ```
DECLARE Count : INTEGER ← 0
DECLARE CurrentLine : STRING
OPENFILE "data.txt" FOR READ
```
3. 循环遍历文件，逐行读取直到到达文件末尾，每次循环递增计数器：
4. ```
WHILE NOT EOF("data.txt") DO
  READLINE "data.txt", CurrentLine
  Count ← Count + 1
ENDWHILE
```
5. 关闭文件，输出最终计数：
6. ```
CLOSEFILE "data.txt"
OUTPUT "Total lines: " + Count
```

**概念自测**

测试你的理解：

1. 要在不删除现有内容的情况下向已有文件末尾添加新数据，应该使用哪种模式？

   - 读取模式
   - 写入模式
   - 追加模式
   - 二进制模式

   *答案:* 追加模式

   *解析:* 正确！追加模式将新数据添加到文件末尾，而写入模式会覆盖整个现有文件。

## 文件错误处理

文件操作经常会在运行时因常见原因失败：文件不存在、权限错误，或存储设备已满。良好的编程习惯要求检查这些错误并妥善处理，而不是让程序崩溃。

**文件未找到错误** — 常见运行时错误，当程序尝试打开指定路径中不存在的文件时发生。

**例题:** 修改上面的行数统计代码，处理`data.txt`不存在的情况。

1. 打开文件后，添加检查确认文件存在，再进行处理：
2. ```
OPENFILE "data.txt" FOR READ
IF NOT FILEEXISTS "data.txt" THEN
  OUTPUT "Error: Input file not found"
  STOP
ENDIF
```
3. 行数统计的其余代码保持不变，但程序会向用户输出清晰的错误消息，而不是意外崩溃。

> **Exam tip**
>
> CIE经常在文件操作题中考察错误处理，因此以读取模式打开文件时一定要添加文件存在性检查。

## 常见错误

- **错误做法:** 打开文件后忘记关闭
  - 原因: 会导致系统资源仍被占用，还可能造成数据没有保存到磁盘
  - 正确做法: 完成对打开文件的操作后，一定要添加显式的`CLOSEFILE`语句
- **错误做法:** 向已有文件添加数据时使用写入模式
  - 原因: 写入模式会覆盖整个现有文件，在添加新数据前清除所有原始内容
  - 正确做法: 要向已有文件末尾添加新数据时使用追加模式
- **错误做法:** 读取下一个条目前不检查EOF
  - 原因: 会导致读取文件结束后的垃圾数据，或在执行过程中出现运行时错误
  - 正确做法: 始终将重复读取操作包装在`WHILE NOT EOF()`循环中，在内容末尾停止
- **错误做法:** 用和二进制文件相同的方式计算文本文件大小
  - 原因: 文本文件将数据存储为可变长度字符，而二进制文件每个数据类型使用固定大小
  - 正确做法: 文本文件通过统计字符数得到大小；二进制文件则用记录数乘以固定记录大小
- **错误做法:** 读取模式下不处理文件缺失的情况
  - 原因: 阅卷官要求健壮的错误处理，未处理的错误会被扣分
  - 正确做法: 以读取模式打开文件后，一定要添加`FILEEXISTS`检查

## 速查表

| 操作 | CIE伪代码 | 常见用途 |
| --- | --- | --- |
| 打开只读 | OPENFILE "f.txt" FOR READ | 读取现有文件 |
| 打开写入 | OPENFILE "f.txt" FOR WRITE | 创建/覆盖文件 |
| 打开追加 | OPENFILE "f.txt" FOR APPEND | 向文件末尾添加数据 |
| 读取行 | READLINE handle, lineVar | 读取一行文本 |
| 写入行 | WRITELINE handle, data | 写入一行输出 |
| 检查文件结束 | NOT EOF(handle) | 循环遍历所有内容 |
| 检查文件存在 | FILEEXISTS "filename" | 处理文件缺失错误 |
| 关闭文件 | CLOSEFILE handle | 保存修改，释放资源 |

## 下一步

文件处理是CIE A-Level计算机科学理论卷和实践卷的核心基础技能。它经常在理论多选题中考察，也是大多数编程实践任务的核心部分，因此掌握完整的文件生命周期对于拿到满分至关重要。在熟练掌握顺序文件处理后，你可以继续学习建立在此基础上的更高级存储概念。你也可以广泛练习错误处理，提高考试中编程的健壮性。

- [面向对象编程概念](https://www.owlsprep.com/zh/study/cie-9618-u11-object-oriented-programming-concepts/)
- [声明式编程概念](https://www.owlsprep.com/zh/study/cie-9618-u11-declarative-programming-concepts/)
- [软件开发](https://www.owlsprep.com/zh/study/cie-9618-u12-overview/)

---

来自 [OwlsPrep](https://www.owlsprep.com) —— A-Level / IB / AP / IGCSE 免费学习指南，依据官方考纲编写。原页面：https://www.owlsprep.com/zh/study/cie-9618-u11-file-handling/
