如果不读取所有内存中的数据并且没有太多复杂性,我将如何做到这一点:
首先计算文件中的最大行长度(使用二进制模式)
with open(inputfile,'rb') as source:
max_line_len = max(len(line) for line in source)
然后使用正确的填充将另一个文件写入磁盘,因此每一行的大小完全相同(您需要两倍以上的大小,但由于您没有内存......)。同时数行数。
with open(inputfile,'rb') as source, open(outputfile,'wb') as dest:
for count,line in enumerate(source):
dest.write(line + b"*"*(max_line_len-len(line))) # write padded
您刚刚创建了一个更大的文件,但现在这些行的长度完全相同。好吧,我们在 后添加了换行符,这在以后会有用。示例输出将是(例如,如果 max len = 20):
the first line
****the second line
***another line
******
(不确定添加的确切星数,但你明白了,注意填充字符无关紧要,只要它不是\n)
这意味着您可以通过简单的乘以 max_line_len 来查找任何行的开头(如记录文件或数据库)
现在您可以生成行索引列表:
indexes = list(range(count+1))
random.shuffle(indexes)
现在迭代这个索引列表,寻找正确的位置,读取一个块并使用我们在换行符之后 填充的事实进行拆分,所以现在我们可以拆分它以丢弃填充内容.
with open(outputfile,'rb') as source:
for idx in indexes:
source.seek(idx * max_line_len)
random_line = source.read(max_line_len).decode().split("\n")[0]
print(random_line) # or store to another file
我尚未对此进行测试,但如果您有足够的磁盘,它应该可以工作。当然,如果你有一根很长的线,其余的都很短,这是非常浪费的。