获取类似csv的解析和行长度字节数?

时间:2016-09-06 19:39:21

标签: python csv

我熟悉csv Python模块,并认为在我的情况下这是必要的,因为我有一些字段包含分隔符(|而不是,,但那是不相关的)在引号内。

但是,我也在寻找每个原始行的字节数长度 previous 来分割成列。我不能指望数据总是引用一列,我不知道/ csv是否会剥离外部引号,所以我不认为(但可能是错误的)只是加入我的分隔符将重现原始行字符串(减少CRLF字符)。意思是,我不肯定以下的工作:

with open(fname) as fh:
    reader = csv.reader(fh, delimiter="|")
    for row in reader:
        original = "|".join(row) ## maybe?

我已经尝试查看csv以查看是否有任何内容我可以使用/ monkey-patch用于此目的,但由于_csv.reader.so,我不知道怎么搞乱。

如果我正在处理XY问题,我的最终目标是通读CSV文件,提取某些字段及其整体文件偏移量,以创建一种查找索引。这样,稍后,当我有一个候选值列表时,我可以检查每个文件的偏移量和seek(),而不是再次查看整个文件。作为一个规模的想法,我可能有100k值来查找10GB文件,所以重新读取文件100k倍对我来说效率不高。我对除CSV模块之外的其他建议持开放态度,但仍需要csv - 就像智能解析行为一样。

编辑:不确定如何使标题和正文已经解释清楚 - 仅仅seek() - 文件句柄是不够的,因为我需要解析这些行为csv以便提取其他信息。

2 个答案:

答案 0 :(得分:5)

您不能将_csv.reader作为子类,但csvfile constructor csv.reader() 参数只需“类似文件”宾语”。这意味着您可以提供自己的类的实例来执行一些预处理 - 例如记住最后一行读取的长度和文件偏移量。这是一个显示确切的实现。请注意,行长包括行尾字符。它还显示了在读取文件后如何存储和使用每行/行的偏移量。

import csv

class CSVInputFile(object):
    """ File-like object. """
    def __init__(self, file):
        self.file = file
        self.offset = None
        self.linelen = None
    def __iter__(self):
        return self
    def __next__(self):
        offset = self.file.tell()
        data = self.file.readline()
        if not data:
            raise StopIteration
        self.offset = offset
        self.linelen = len(data)
        return data
    next = __next__

offsets = []  # remember where each row starts
fname = 'unparsed.csv'
with open(fname) as fh:
    csvfile = CSVInputFile(fh)
    for row in csv.reader(csvfile, delimiter="|"):
        print('offset: {}, linelen: {}, row: {}'.format(
            csvfile.offset, csvfile.linelen, row))  # file offset and length of row
        offsets.append(csvfile.offset)  # remember where each row started

答案 1 :(得分:2)

根据性能要求和数据大小,低技术解决方案是简单地读取文件两次。首先获取每行的长度,然后通过csv解析器运行数据。在我有点过时的Mac上,我可以在一秒钟内读取和计算2-3百万行的长度,这不是一个巨大的性能影响。