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 教程。