从 RAM 读取 CSV 文件
Reading CSV files from RAM
情况:我使用 mmap 将 CVD(ClamAV 病毒数据库)文件加载到 RAM 中。 CVD 文件中每一行的格式与 CSV 文件中的格式相同(以“:”分隔)。下面是代码片段:
def mapping():
with open("main.cvd", 'rt') as f:
global mapper
mapper = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
csv.register_dialect('delimit', delimiter=':', quoting=csv.QUOTE_NONE)
def compare(hashed):
for row in csv.reader(mapper, dialect='delimit'):
if row[1] == hashed:
print('Found!')
问题:当运行时,它returns错误_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
问题:如何将 CSV 文件读取为已加载到内存中的文本?
附加信息 1:我尝试使用 StringIO
,它抛出错误 TypeError: initial_value must be str or None, not mmap.mmap
附加信息 2:我需要将文件放在 RAM 中以便更快地访问文件,我不能牺牲时间使用 readline()
等函数逐行读取它
csv.reader
构造函数的 csvfile
参数 "can be any object which supports the iterator protocol and returns a string each time its next()
method is called"。
这意味着 "object" 可以是生成器函数或生成器表达式。在下面的代码中,我实现了一个名为 mmap_file_reader()
的生成器函数,它将内存映射中的字节转换为字符串,并且 yield
它检测到的每一行输出。
我将 mmap.mmap
构造函数调用设置为有条件的,因此它也适用于 Windows。如果您使用 access=
关键字而不是 prot=
关键字,则这不是必需的——但我无法测试它,所以如图所示。
import csv
import mmap
import sys
def mapping():
with open("main.cvd", 'rt') as f:
global mapper
if sys.platform.startswith('win32'):
mmf = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) # windows
else:
mmf = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) # unix
mapper = mmap_file_reader(mmf)
csv.register_dialect('delimit', delimiter=':', quoting=csv.QUOTE_NONE)
def mmap_file_reader(mmf):
'''Yield successive lines of the given memory-mapped file as strings.
Generator function which reads and converts the bytes of the given mmapped file
to strings and yields them one line at a time.
'''
while True:
line = mmf.readline()
if not line: # EOF?
return
yield str(line, encoding='utf-8') # convert bytes of lineread into a string
def compare(hashed):
for row in csv.reader(mapper, dialect='delimit'):
if row[1] == hashed:
print('Found!')
情况:我使用 mmap 将 CVD(ClamAV 病毒数据库)文件加载到 RAM 中。 CVD 文件中每一行的格式与 CSV 文件中的格式相同(以“:”分隔)。下面是代码片段:
def mapping():
with open("main.cvd", 'rt') as f:
global mapper
mapper = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
csv.register_dialect('delimit', delimiter=':', quoting=csv.QUOTE_NONE)
def compare(hashed):
for row in csv.reader(mapper, dialect='delimit'):
if row[1] == hashed:
print('Found!')
问题:当运行时,它returns错误_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
问题:如何将 CSV 文件读取为已加载到内存中的文本?
附加信息 1:我尝试使用 StringIO
,它抛出错误 TypeError: initial_value must be str or None, not mmap.mmap
附加信息 2:我需要将文件放在 RAM 中以便更快地访问文件,我不能牺牲时间使用 readline()
csv.reader
构造函数的 csvfile
参数 "can be any object which supports the iterator protocol and returns a string each time its next()
method is called"。
这意味着 "object" 可以是生成器函数或生成器表达式。在下面的代码中,我实现了一个名为 mmap_file_reader()
的生成器函数,它将内存映射中的字节转换为字符串,并且 yield
它检测到的每一行输出。
我将 mmap.mmap
构造函数调用设置为有条件的,因此它也适用于 Windows。如果您使用 access=
关键字而不是 prot=
关键字,则这不是必需的——但我无法测试它,所以如图所示。
import csv
import mmap
import sys
def mapping():
with open("main.cvd", 'rt') as f:
global mapper
if sys.platform.startswith('win32'):
mmf = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) # windows
else:
mmf = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) # unix
mapper = mmap_file_reader(mmf)
csv.register_dialect('delimit', delimiter=':', quoting=csv.QUOTE_NONE)
def mmap_file_reader(mmf):
'''Yield successive lines of the given memory-mapped file as strings.
Generator function which reads and converts the bytes of the given mmapped file
to strings and yields them one line at a time.
'''
while True:
line = mmf.readline()
if not line: # EOF?
return
yield str(line, encoding='utf-8') # convert bytes of lineread into a string
def compare(hashed):
for row in csv.reader(mapper, dialect='delimit'):
if row[1] == hashed:
print('Found!')