Unix/Linux系统编程学习笔记第九章
知识点归纳以及最有收获的内容
- I/O库函数知识点总结
1. 文件操作
- open()函数:用于打开文件,可以指定文件名、模式(读取、写入、追加等)以及编码。
- 文件模式(mode):包括读取模式('r')、写入模式('w')、追加模式('a')、二进制模式('b')等。
- close()函数:用于关闭已打开的文件,释放资源。
- with语句:可以自动管理文件的打开和关闭,减少资源泄漏的风险。
2. 读取文件内容
- read()方法:用于读取整个文件的内容,可以指定读取的字符数。
- readline()方法:用于逐行读取文件内容。
- readlines()方法:将文件内容按行读取到列表中。
- for循环:可以用于逐行遍历文件内容。
3. 写入文件内容
- write()方法:用于向文件中写入数据,可以是字符串或二进制数据。
- writelines()方法:将字符串列表写入文件。
- seek()方法:用于移动文件指针到指定位置,以实现随机写入。
4. 文件迭代
- for循环:可以用于逐行迭代文件内容,特别适用于大文件。
5. 文件对象属性
- name属性:表示文件的名称。
- mode属性:表示文件的打开模式。
- closed属性:表示文件是否已关闭。
6. 异常处理
- try...except语句:用于捕获文件操作可能引发的异常,如文件不存在、权限问题等。
7. 目录操作
- os模块:提供了一系列用于处理文件和目录的函数,如创建目录、删除目录、列出目录内容等。
8. 标准输入和标准输出
- sys.stdin:标准输入流对象,用于从键盘读取用户输入。
- sys.stdout:标准输出流对象,用于向屏幕输出内容。
- sys.stderr:标准错误流对象,用于输出错误信息。
9. 二进制文件操作
- 二进制模式('b'):可以用于处理图像、音频等二进制文件。
- rb和wb模式:分别用于读取和写入二进制文件。
10. 缓冲区
- 缓冲区:用于临时存储数据,以提高I/O性能。
- buffered属性:文件对象的属性,用于检查文件是否使用了缓冲区。
11. 文件的位置和指针
- tell()方法:用于获取文件指针的当前位置。
- seek()方法:用于移动文件指针到指定位置。
12. 文本编码和字符集
- 文本编码:表示文件中字符的编码方式,如UTF-8、ISO-8859-1等。
- encoding属性:用于获取文件的编码。
- open()函数的encoding参数:用于指定文件的编码。
13. 文件模式附加选项
- +号:可以与文件模式一起使用,用于支持读写模式,如'r+'和'w+'。
14. 文件的复制和移动
- shutil模块:提供了用于复制和移动文件的函数,如shutil.copy()和shutil.move()。
苏格拉底挑战
问题与解决思路
当进行I/O文件读写时,常见的问题包括文件不存在、权限问题、编码错误、内存消耗过大等。
- 总结如下
文件不存在问题:
- 问题描述: 尝试打开或读取一个不存在的文件,导致FileNotFoundError。
- 解决方式:
在打开文件前,确保文件存在,可以使用os.path.exists()来检查。
使用try...except块来捕获FileNotFoundError并进行适当的错误处理
import os
file_path = "example.txt"
if os.path.exists(file_path):
with open(file_path, 'r') as file:
content = file.read()
else:
print(f"File '{file_path}' does not exist.")
权限问题:
- 问题描述: 尝试读取或写入一个没有权限的文件,导致PermissionError。
- 解决方式:
确保你具有足够的权限来访问文件。
如果是在Linux或类Unix系统上,可以使用chmod命令更改文件的权限。
在Windows上,确保文件没有被其他程序锁定。
编码错误:
- 问题描述: 尝试使用错误的编码方式读取文本文件,导致UnicodeDecodeError或乱码。
- 解决方式:
使用正确的编码方式打开文件,通常是UTF-8。
在打开文件时,指定正确的编码方式,如open('file.txt', 'r', encoding='utf-8')。
使用异常处理来处理编码错误,例如将错误字符替换为占位符。
try:
with open('file.txt', 'r', encoding='utf-8') as file:
content = file.read()
except UnicodeDecodeError:
print("Encoding error: Unable to decode file.")
内存消耗过大:
- 问题描述: 尝试一次性读取大文件的全部内容,导致内存消耗过大,可能引发MemoryError。
- 解决方式:
逐行或逐块读取文件,以减少内存消耗。
使用生成器(Generator)来处理大文件,以节省内存。
def read_large_file(file_path):
with open(file_path, 'r') as file:
for line in file:
yield line
实践过程
创建并写入文件:
#include <stdio.h>
int main() {
// 创建文件并打开以写入模式
FILE *file = fopen("example.txt", "w");
// 检查文件是否成功打开
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 写入数据到文件
fprintf(file, "Hello, world!\n");
fprintf(file, "This is a C programming example.\n");
printf("已经成功写入");
// 关闭文件
fclose(file);
return 0;
}
读取文件内容:
#include <stdio.h>
int main() {
// 打开文件以读取模式
FILE *file = fopen("example.txt", "r");
// 检查文件是否成功打开
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 读取文件内容并打印
char buffer[100]; // 缓冲区
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("%s", buffer);
}
// 关闭文件
fclose(file);
return 0;
}
3. 追加内容到文件:
#include <stdio.h>
int main() {
// 打开文件以追加模式
FILE *file = fopen("example.txt", "a");
// 检查文件是否成功打开
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 写入数据到文件
fprintf(file, "This line is appended.\n");
// 关闭文件
fclose(file);
return 0;
}