有没有一种Python文件类型可以访问随机行而不必遍历整个文件?我需要在一个大文件中进行搜索,读取整个文件到内存中是不可能的。
任何类型或方法都将不胜感激。
有没有一种Python文件类型可以访问随机行而不必遍历整个文件?我需要在一个大文件中进行搜索,读取整个文件到内存中是不可能的。
任何类型或方法都将不胜感激。
看起来像是 mmap
设计的典型应用场景。一个 mmap
对象可以创建一个类似于字符串的接口来操作文件:
>>> f = open("bonnie.txt", "wb")
>>> f.write("My Bonnie lies over the ocean.")
>>> f.close()
>>> f.open("bonnie.txt", "r+b")
>>> mm = mmap(f.fileno(), 0)
>>> print mm[3:9]
Bonnie
如果你想知道,mmap
对象也可以被赋值:
>>> print mm[24:]
ocean.
>>> mm[24:] = "sea. "
>>> print mm[:]
My Bonnie lies over the sea.
mm = mmap(f.fileno(), 0)
(据我所知)会将整个文件读入内存。您能详细说明一下吗? - Olegimport linecache
print linecache.getline(your_file.txt, randomLineNumber) # Note: first line is 1, not 0
由于行的长度可以是任意的,因此您无法在不遍历整个文件的情况下获取随机行(无论您是指“其编号实际上是随机的行”还是“我选择的任意编号的行”)。
如果您只需要类似随机的效果,则可以将光标定位到文件中的一个随机位置,然后向前读取,直到遇到行终止符。但如果您想找到(比如)第1234行,则这种方法就没有用了,并且如果您真的想要一个随机选择的行,则会对行进行非均匀采样。
文件对象具有seek方法,可以将文件指针定位到特定的字节位置。 为了遍历大文件,可以迭代文件并在每行中检查该值。迭代文件对象不会将整个文件内容加载到内存中。
是的,你可以很容易地获取一条随机行。只需在文件中搜索到随机位置,然后向开头搜索直到遇到 \n 或文件开头,然后读取一行。
代码:
import sys,random
with open(sys.argv[1],"r") as f:
f.seek(0,2) # seek to end of file
bytes = f.tell()
f.seek(int(bytes*random.random()))
# Now seek forward until beginning of file or we get a \n
while True:
f.seek(-2,1)
ch = f.read(1)
if ch=='\n': break
if f.tell()==1: break
# Now get a line
print f.readline()
文件对象支持 seek,但请确保以二进制形式打开它们,即 "rb"。
如果数据已经处于内部格式中,则您可能还希望使用 mmap 模块进行随机访问。
记录长度固定吗?如果是,那么可以使用寻址实现二分查找算法。
否则,将文件加载到SQLlite数据库中。查询该数据库。