第九章学习笔记

发布时间 2023-09-17 11:07:40作者: 20211308wjc

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;
}