Python os.truncate 函数
上次修改时间:2025 年 4 月 11 日
本全面指南探讨 Python 的 os.truncate
函数,该函数通过截断或扩展文件大小来修改文件。我们将介绍使用场景、权限要求和实际示例。
基本定义
os.truncate
函数将文件大小更改为指定的长度。如果文件被扩展,则新字节将填充零。
关键参数:path (要修改的文件),length (以字节为单位的新大小)。需要对文件具有写入权限。适用于常规文件,不适用于目录。
将文件截断为更小的大小
os.truncate
最常见的用途是通过丢弃超出指定长度的内容来减小文件大小。此示例演示了基本截断。
import os # Create a sample file file_path = "data.txt" with open(file_path, "w") as f: f.write("This is some sample text for truncation demonstration.") # Check original size original_size = os.path.getsize(file_path) print(f"Original size: {original_size} bytes") # Truncate to 20 bytes os.truncate(file_path, 20) new_size = os.path.getsize(file_path) print(f"New size: {new_size} bytes") # Verify content with open(file_path) as f: print(f"Content: '{f.read()}'")
这会创建一个文件,然后将其截断为 20 字节。剩余内容将是原始文本的前 20 个字节。
请注意,截断会立即在文件系统级别发生,而无需重新打开文件。
用零扩展文件
当指定的长度大于当前文件大小时,os.truncate
会通过填充空字节来扩展文件。此示例显示文件扩展。
import os file_path = "empty.dat" # Create empty file with open(file_path, "w"): pass # Extend file to 1KB (1024 bytes) os.truncate(file_path, 1024) size = os.path.getsize(file_path) print(f"File size after extension: {size} bytes") # Verify content is null bytes with open(file_path, "rb") as f: content = f.read(16) # Read first 16 bytes print(f"First 16 bytes: {content}")
这会创建一个空文件,然后将其扩展到 1024 字节。新空间将填充零。二进制模式用于读取空字节。
文件扩展对于预分配空间或创建稀疏文件很有用。
截断打开的文件描述符
os.ftruncate
的工作方式类似,但操作的是打开的文件描述符而不是路径。此示例显示了两个函数以进行比较。
import os file_path = "log.txt" # Using os.truncate with path with open(file_path, "w") as f: f.write("Initial content for truncation test") os.truncate(file_path, 10) print(f"After path truncate: {os.path.getsize(file_path)} bytes") # Using os.ftruncate with file descriptor with open(file_path, "r+") as f: fd = f.fileno() os.ftruncate(fd, 5) print(f"After fd truncate: {os.path.getsize(file_path)} bytes")
这两个函数都实现了相同的结果,但采用不同的参数。 os.ftruncate
需要一个打开的文件描述符。
必须以允许写入的模式打开文件才能使用 os.ftruncate
。
错误处理
os.truncate
可能会引发各种异常。此示例演示了针对常见场景的正确错误处理。
import os import errno file_path = "protected.txt" try: # Attempt to truncate a non-existent file os.truncate("nonexistent.txt", 100) except FileNotFoundError: print("Error: File not found") try: # Attempt to truncate without permissions os.truncate("/root/protected.txt", 100) except PermissionError: print("Error: Permission denied") try: # Attempt to truncate a directory os.truncate("/tmp", 100) except IsADirectoryError: print("Error: Cannot truncate a directory") try: # Invalid length os.truncate(file_path, -1) except OSError as e: if e.errno == errno.EINVAL: print("Error: Invalid length specified")
这显示了处理找不到文件、权限问题、目录截断和无效长度参数的情况。 每种情况都会引发不同的异常。
在处理文件系统操作时,始终验证输入并处理潜在的错误。
与其他文件操作结合使用
os.truncate
可以与其他文件操作结合使用,以实现更复杂的工作流程。此示例显示了与文件读取的集成。
import os file_path = "data.bin" # Create binary file with some data with open(file_path, "wb") as f: f.write(b"\x01\x02\x03\x04\x05\x06\x07\x08") # Truncate to remove last 4 bytes os.truncate(file_path, 4) # Read remaining content with open(file_path, "rb") as f: content = f.read() print(f"Remaining bytes: {content}") print(f"Size after truncate: {len(content)} bytes") # Extend file and verify os.truncate(file_path, 8) with open(file_path, "rb") as f: content = f.read() print(f"Extended bytes: {content}") print(f"Size after extension: {len(content)} bytes")
这将创建一个二进制文件,将其截断,然后在验证每一步的内容的同时对其进行扩展。在扩展期间添加的空字节是可见的。
使用非文本数据或检查扩展期间添加的实际字节时,二进制模式至关重要。
性能注意事项
此示例将 os.truncate
与文件大小修改的替代方法进行基准测试,以演示性能特征。
import os import timeit file_path = "large_file.bin" size_mb = 10 # 10MB file test_size = 5 # Truncate to 5MB def create_large_file(): with open(file_path, "wb") as f: f.seek(size_mb * 1024 * 1024 - 1) f.write(b"\0") def method_truncate(): os.truncate(file_path, test_size * 1024 * 1024) def method_write(): with open(file_path, "r+") as f: f.truncate(test_size * 1024 * 1024) # Setup create_large_file() # Benchmark truncate_time = timeit.timeit(method_truncate, number=100) write_time = timeit.timeit(method_write, number=100) print(f"os.truncate average: {truncate_time/100:.6f}s") print(f"file.truncate average: {write_time/100:.6f}s") # Cleanup os.remove(file_path)
这将创建一个大文件,然后比较截断方法。 os.truncate
通常更快,因为它在文件系统级别运行。
文件越大,截断操作越频繁,性能差异就越明显。
安全注意事项
- 权限要求: 需要对文件具有写入权限
- 数据丢失: 截断会永久删除文件内容
- 竞争条件: 文件可能在大小检查和截断之间发生更改
- 符号链接: 默认情况下遵循符号链接 (使用 os.path.realpath)
- 跨平台: 在 Unix 和 Windows 上的行为一致
最佳实践
- 备份重要数据: 在执行破坏性操作之前
- 检查文件类型: 在截断之前验证它是否是常规文件
- 处理错误: 实施适当的异常处理
- 记录大小更改: 记录截断操作以进行审核
- 考虑替代方案: 对于某些情况,file.truncate() 可能会更好
资料来源
作者
列出所有 Python 教程。