我是python的新手。我想读取一个文件并将数据复制到另一个文件。我的代码如下。在下面的代码中,当我在for循环中打开文件时,可以将所有数据写入dst_file中。但是写入dst_file却需要8秒。
for cnt, hex_num in enumerate(hex_data):
with open(src_file, "r") as src_f, open(dst_file, "a") as dst_f:
copy_flag = False
for src_line in src_f:
if r"SPI_frame_0" in src_line:
src_line = src_line.replace('SPI_frame_0', 'SPI_frame_' + str(cnt))
copy_flag = True
if r"halt" in src_line:
copy_flag = False
if copy_flag:
copy_mid_data += src_line
updated_data = WriteHexData(copy_mid_data, hex_num, cnt, msb_lsb_flag)
copy_mid_data = ""
dst_f.write(updated_data)
为了提高性能,我试图在for循环之外打开文件。但它不能正常工作。它仅在dst_file
中写入一次(for循环的一个迭代)。如下所示。
with open(src_file, "r") as src_f, open(dst_file, "a") as dst_f:
for cnt, hex_num in enumerate(hex_data):
copy_flag = False
for src_line in src_f:
if r"SPI_frame_0" in src_line:
src_line = src_line.replace('SPI_frame_0', 'SPI_frame_' + str(cnt))
copy_flag = True
if r"halt" in src_line:
copy_flag = False
if copy_flag:
copy_mid_data += src_line
updated_data = WriteHexData(copy_mid_data, hex_num, cnt, msb_lsb_flag)
copy_mid_data = ""
dst_f.write(updated_data)
有人可以帮我发现我的错误吗?
答案 0 :(得分:0)
文件是迭代器。循环遍历它们会逐行读取文件。 直到您结束。然后,当您尝试阅读更多内容时,他们不仅会回到开始。在文件对象上进行新的for
循环不会“重置”文件。
在循环中每次都重新打开输入文件,或者显式地找回起点,或者只读取一次文件。您可以使用src_f.seek(0)
进行查找,重新打开意味着您需要使用两个with
语句(一个语句一次打开输出文件,另一个语句在for
循环中处理{{1} }源文件)。
在这种情况下,假设您要一次性建立要写入内存的数据,我将只读取一次输入文件,只保留需要复制的行。
您可以在同一文件对象上使用多个src_f
循环,文件位置将相应更改。这使得从一个键串的匹配到另一键串的匹配读取一系列行非常简单。 itertools.takewhile()
function使其更容易:
for
请注意,我将from itertools import takewhile
# read the correct lines (from SPI_frame_0 to halt) from the source file
lines = []
with open(src_file, "r") as src_f:
for line in src_f:
if r"SPI_frame_0" in line:
lines.append(line)
# read additional lines until we find 'halt'
lines += takewhile(lambda l: 'halt' not in l, src_f)
# transform the source lines with a new counter
with open(dst_file, "a") as dst_f:
for cnt, hex_num in enumerate(hex_data):
copy_mid_data = []
for line in lines:
if "SPI_frame_0" in line:
line = line.replace('SPI_frame_0', 'SPI_frame_{}'.format(cnt))
copy_mid_data.append(line)
updated_data = WriteHexData(''.join(copy_mid_data), hex_num, cnt, msb_lsb_flag)
dst_f.write(updated_data)
更改为列表,以避免二次字符串复制;一次连接一个字符串列表要高效得多。