06.python中文件的读写练习题

Python文件读写练习题

练习1:文件复制器

题目描述

编写一个函数,将一个文件的内容复制到另一个文件。

要求

  • 函数应该接受源文件路径和目标文件路径作为参数
  • 需要处理文件不存在等异常情况
  • 使用with语句确保文件正确关闭
  • 支持文本文件和二进制文件的复制

示例代码

def copy_file(source_path, target_path):
    """
    复制文件内容

    参数:
        source_path: 源文件路径
        target_path: 目标文件路径
    """
    try:
        # 使用二进制模式打开,可以复制任何类型的文件
        with open(source_path, 'rb') as source:
            with open(target_path, 'wb') as target:
                # 逐块读取,避免大文件占用过多内存
                while True:
                    chunk = source.read(1024)  # 每次读取1KB
                    if not chunk:
                        break
                    target.write(chunk)
        print(f"文件复制成功:{source_path} -> {target_path}")
        return True
    except FileNotFoundError:
        print(f"错误:源文件 {source_path} 不存在")
        return False
    except PermissionError:
        print(f"错误:没有权限访问文件")
        return False
    except Exception as e:
        print(f"错误:{str(e)}")
        return False

# 使用示例
if __name__ == "__main__":
    # 复制文本文件
    copy_file("source.txt", "target.txt")

    # 复制图片文件
    copy_file("image.jpg", "image_copy.jpg")

进阶练习

  • 添加进度显示功能
  • 支持复制整个目录
  • 添加文件大小比较验证

练习2:行号添加器

题目描述

编写一个程序,读取文件并在每行前添加行号,然后保存到新文件。

要求

  • 读取源文件的所有行
  • 在每行前添加行号(从1开始)
  • 行号格式:行号: 内容
  • 将结果保存到新文件

示例代码

def add_line_numbers(source_path, target_path):
    """
    为文件添加行号

    参数:
        source_path: 源文件路径
        target_path: 目标文件路径
    """
    try:
        with open(source_path, 'r', encoding='utf-8') as source:
            lines = source.readlines()

        with open(target_path, 'w', encoding='utf-8') as target:
            for line_num, line in enumerate(lines, start=1):
                # 保留原行的换行符,如果行末尾没有换行符则添加
                if line.endswith('n'):
                    target.write(f"{line_num}: {line}")
                else:
                    target.write(f"{line_num}: {line}n")

        print(f"行号添加成功:{target_path}")
        return True
    except FileNotFoundError:
        print(f"错误:文件 {source_path} 不存在")
        return False
    except Exception as e:
        print(f"错误:{str(e)}")
        return False

# 使用示例
if __name__ == "__main__":
    add_line_numbers("source.txt", "numbered.txt")

输入文件示例(source.txt)

第一行内容
第二行内容
第三行内容

输出文件示例(numbered.txt)

1: 第一行内容
2: 第二行内容
3: 第三行内容

进阶练习

  • 支持自定义行号格式(如:[001], Line 1:等)
  • 支持跳过空行不添加行号
  • 支持指定起始行号

练习3:文件比较器

题目描述

编写一个函数,比较两个文件的内容是否相同。

要求

  • 比较两个文件的内容是否完全相同
  • 返回布尔值表示是否相同
  • 处理文件不存在的情况
  • 支持文本文件和二进制文件的比较

示例代码

import os

def compare_files(file1_path, file2_path):
    """
    比较两个文件是否相同

    参数:
        file1_path: 第一个文件路径
        file2_path: 第二个文件路径

    返回:
        True: 文件相同
        False: 文件不同或文件不存在
    """
    try:
        # 检查文件是否存在
        if not os.path.exists(file1_path):
            print(f"错误:文件 {file1_path} 不存在")
            return False

        if not os.path.exists(file2_path):
            print(f"错误:文件 {file2_path} 不存在")
            return False

        # 比较文件大小
        size1 = os.path.getsize(file1_path)
        size2 = os.path.getsize(file2_path)

        if size1 != size2:
            print(f"文件大小不同:{file1_path} ({size1} bytes) vs {file2_path} ({size2} bytes)")
            return False

        # 逐字节比较文件内容
        with open(file1_path, 'rb') as f1:
            with open(file2_path, 'rb') as f2:
                while True:
                    chunk1 = f1.read(1024)
                    chunk2 = f2.read(1024)

                    if chunk1 != chunk2:
                        print("文件内容不同")
                        return False

                    if not chunk1:  # 读取完毕
                        break

        print("两个文件完全相同")
        return True

    except Exception as e:
        print(f"错误:{str(e)}")
        return False

# 使用示例
if __name__ == "__main__":
    # 比较两个文件
    result = compare_files("file1.txt", "file2.txt")
    print(f"比较结果:{result}")

进阶练习

  • 显示第一个不同的位置
  • 支持忽略空白字符的比较
  • 支持忽略大小写的比较(仅文本文件)
  • 生成差异报告

练习4:单词计数器

题目描述

编写一个程序,统计文件中每个单词出现的次数。

要求

  • 读取文件内容
  • 统计每个单词的出现次数
  • 忽略大小写(可选)
  • 按出现次数降序排列
  • 输出统计结果

示例代码

import re
from collections import Counter

def count_words(file_path, ignore_case=True):
    """
    统计文件中每个单词的出现次数

    参数:
        file_path: 文件路径
        ignore_case: 是否忽略大小写,默认True

    返回:
        Counter对象,包含单词及其出现次数
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 使用正则表达式提取单词(字母、数字、下划线、连字符)
        # b 表示单词边界
        words = re.findall(r'b[a-zA-Z0-9_-]+b', content)

        if ignore_case:
            # 转换为小写进行统计
            words = [word.lower() for word in words]

        # 使用Counter统计
        word_count = Counter(words)

        return word_count

    except FileNotFoundError:
        print(f"错误:文件 {file_path} 不存在")
        return None
    except Exception as e:
        print(f"错误:{str(e)}")
        return None

def print_word_statistics(word_count, top_n=10):
    """
    打印单词统计结果

    参数:
        word_count: Counter对象
        top_n: 显示前N个最常见的单词
    """
    if word_count is None:
        return

    print(f"n总共有 {len(word_count)} 个不同的单词")
    print(f"总单词数:{sum(word_count.values())}")
    print(f"n出现次数最多的前 {top_n} 个单词:")
    print("-" * 40)

    for word, count in word_count.most_common(top_n):
        print(f"{word:20s} : {count:5d}")

# 使用示例
if __name__ == "__main__":
    # 统计单词
    word_count = count_words("text.txt", ignore_case=True)

    if word_count:
        # 打印统计结果
        print_word_statistics(word_count, top_n=20)

        # 保存结果到文件
        with open("word_statistics.txt", 'w', encoding='utf-8') as output:
            output.write("单词统计结果n")
            output.write("=" * 40 + "n")
            for word, count in word_count.most_common():
                output.write(f"{word:20s} : {count:5d}n")
        print("n统计结果已保存到 word_statistics.txt")

输入文件示例(text.txt)

Python is a great programming language.
Python is easy to learn and powerful.
Many developers love Python.

输出示例

总共有 12 个不同的单词
总单词数:18

出现次数最多的前 10 个单词:
----------------------------------------
python                :     3
is                    :     2
a                     :     1
great                 :     1
programming           :     1
language              :     1
easy                  :     1
to                    :     1
learn                 :     1
and                   :     1

进阶练习

  • 支持自定义分隔符
  • 过滤停用词(如:the, a, an, is等)
  • 支持统计中文字词
  • 生成词云图

练习5:配置文件解析器

题目描述

编写一个程序,解析类似INI格式的配置文件。

要求

  • 解析INI格式的配置文件
  • 支持节(section):[section_name]
  • 支持键值对:key = value
  • 忽略注释行(以#;开头)
  • 忽略空行
  • 提供读取配置的方法

示例代码

import re
from typing import Dict, Optional

class ConfigParser:
    """INI格式配置文件解析器"""

    def __init__(self, config_path):
        """
        初始化配置解析器

        参数:
            config_path: 配置文件路径
        """
        self.config_path = config_path
        self.config = {}  # 存储解析后的配置
        self.current_section = None
        self._parse()

    def _parse(self):
        """解析配置文件"""
        try:
            with open(self.config_path, 'r', encoding='utf-8') as file:
                for line_num, line in enumerate(file, start=1):
                    # 去除首尾空白字符
                    line = line.strip()

                    # 跳过空行
                    if not line:
                        continue

                    # 跳过注释行(以#或;开头)
                    if line.startswith('#') or line.startswith(';'):
                        continue

                    # 匹配节(section)
                    section_match = re.match(r'^[(.+)]$', line)
                    if section_match:
                        section_name = section_match.group(1).strip()
                        self.current_section = section_name
                        if section_name not in self.config:
                            self.config[section_name] = {}
                        continue

                    # 匹配键值对
                    key_value_match = re.match(r'^([^=]+)=(.*)$', line)
                    if key_value_match:
                        key = key_value_match.group(1).strip()
                        value = key_value_match.group(2).strip()

                        # 如果没有节,使用默认节
                        if self.current_section is None:
                            self.current_section = 'DEFAULT'
                            if self.current_section not in self.config:
                                self.config[self.current_section] = {}

                        self.config[self.current_section][key] = value
                    else:
                        print(f"警告:第 {line_num} 行格式不正确:{line}")

        except FileNotFoundError:
            print(f"错误:配置文件 {self.config_path} 不存在")
        except Exception as e:
            print(f"错误:解析配置文件时出错 - {str(e)}")

    def get(self, section: str, key: str, default: Optional[str] = None) -> Optional[str]:
        """
        获取配置值

        参数:
            section: 节名
            key: 键名
            default: 默认值

        返回:
            配置值,如果不存在返回default
        """
        return self.config.get(section, {}).get(key, default)

    def get_section(self, section: str) -> Dict[str, str]:
        """
        获取整个节的配置

        参数:
            section: 节名

        返回:
            该节的所有键值对字典
        """
        return self.config.get(section, {})

    def get_all_sections(self) -> list:
        """获取所有节名"""
        return list(self.config.keys())

    def print_config(self):
        """打印所有配置"""
        print("n配置文件内容:")
        print("=" * 50)
        for section, items in self.config.items():
            print(f"n[{section}]")
            for key, value in items.items():
                print(f"  {key} = {value}")

# 使用示例
if __name__ == "__main__":
    # 创建配置文件示例
    config_content = """# 数据库配置
[database]
host = localhost
port = 3306
username = admin
password = secret123
database = mydb

# 应用配置
[application]
name = MyApp
version = 1.0.0
debug = true
log_level = INFO

# 服务器配置
[server]
host = 0.0.0.0
port = 8080
timeout = 30
"""

    # 写入配置文件
    with open("config.ini", 'w', encoding='utf-8') as f:
        f.write(config_content)

    # 解析配置文件
    parser = ConfigParser("config.ini")

    # 打印所有配置
    parser.print_config()

    # 获取特定配置
    print("n" + "=" * 50)
    print("获取特定配置:")
    db_host = parser.get("database", "host")
    db_port = parser.get("database", "port")
    app_name = parser.get("application", "name")

    print(f"数据库主机:{db_host}")
    print(f"数据库端口:{db_port}")
    print(f"应用名称:{app_name}")

    # 获取整个节
    print("n" + "=" * 50)
    print("服务器配置:")
    server_config = parser.get_section("server")
    for key, value in server_config.items():
        print(f"  {key}: {value}")

配置文件示例(config.ini)

# 数据库配置
[database]
host = localhost
port = 3306
username = admin
password = secret123
database = mydb

# 应用配置
[application]
name = MyApp
version = 1.0.0
debug = true
log_level = INFO

# 服务器配置
[server]
host = 0.0.0.0
port = 8080
timeout = 30

输出示例

配置文件内容:
==================================================

[database]
  host = localhost
  port = 3306
  username = admin
  password = secret123
  database = mydb

[application]
  name = MyApp
  version = 1.0.0
  debug = true
  log_level = INFO

[server]
  host = 0.0.0.0
  port = 8080
  timeout = 30

==================================================
获取特定配置:
数据库主机:localhost
数据库端口:3306
应用名称:MyApp

进阶练习

  • 支持嵌套节
  • 支持数据类型转换(int, float, bool等)
  • 支持配置验证
  • 支持写入配置文件
  • 支持环境变量替换

总结

这些练习题涵盖了Python文件操作的主要方面:

  1. 文件复制器:练习基本的文件读写操作
  2. 行号添加器:练习逐行处理文件内容
  3. 文件比较器:练习文件内容的比较和验证
  4. 单词计数器:练习文本处理和数据分析
  5. 配置文件解析器:练习复杂文本解析和数据结构

每个练习都包含了:

  • 清晰的题目描述
  • 完整的功能要求
  • 可运行的示例代码
  • 使用示例和输出示例
  • 进阶练习建议

建议按照顺序完成这些练习,逐步提高文件操作的技能水平。

发表评论