【问题标题】:Why is csvreader for Python starting good then producing NULL bytes?为什么 Python 的 csvreader 开始良好然后产生 NULL 字节?
【发布时间】:2015-11-14 05:46:28
【问题描述】:

好的,我正在阅读一份 Excel 工作簿。我读了一段时间文件,它在调试并在代码下方执行其他操作后从 .csv 开始,我向您展示它已更改为 xlsx 我开始收到 IOError 没有这样的文件或目录。我弄清楚了原因并将 FFA.csv 更改为 FFA.xlsx,它可以正常工作。然后我开始做其他事情和调试。今天早上起床,现在我收到以下错误:行包含 NULL 字节。很奇怪,因为代码开始时很好。现在无法读取。我放入 print repr() 进行调试,它实际上现在打印 NULL 字节。那么我该如何解决这个问题并在将来防止它呢?这是第一个 200 字节:

PK\x03\x04\x14\x00\x06\x00\x08\x00\x00\x00!\x00b\xee\x9dh^\x01\x00\x00\x90\x04\x00\x00\x13\x00\x08\x02[Content_Types].xml \xa2\x04\x02(\xa0\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

import csv

def readFile():
    count = 0
    print repr(open("FFA.xlsx", "rb").read(200)) #dump 1st 200 bytes
    with open("FFA.xlsx","rb") as csvfile:
        FFAreader = csv.reader(csvfile, delimiter=",")
        for row in FFAreader:
            idd = row[0]
            name = row[1]
            pos = row[2]
            team = row[3]
            pts = row[4]
            oecr = row[5]
            oR = row[6]
            posR = row[7]
            up = row[8]
            low =row[9]
            risk = row[10]
            swing = row[11]
 readFile()

【问题讨论】:

  • 呃,.xlsx 不是 csv 文件。它是一个包含多个 xml 和其他文件的 zip 文件。你正在阅读二进制垃圾。
  • 好吧,就像我说的,我只是改变了它,因为它似乎会改变自己,但它在一段时间内工作正常。我将其改回 .csv 但仍然收到错误消息。但是前 200 个字节已更改为
  • 这是现在的前 200 个字节 'playerId,playername,position,team,points,overallECR,overallRank,positionRank,upper,lower,risk,swing\r\n100029,49ers,DST,SF, 104.896,245,979,16,165.7802,92.0755,4.0319,73.7047\r\n2543501,Aaron Colvin,DB,JAC'
  • 将文件导出为 CSV,然后处理 CSV 文件。
  • 作为附加建议,您应该在 main 的常规块之后调用 readFile() 方法:` if name == 'main': readFile() `

标签: excel python-2.7 csv null byte


【解决方案1】:

您发布的代码有一个小而危险的错误,因为您通过两次打开文件句柄来泄漏文件句柄。

1) 您正在打开文件并从中读取 200 个字节,但没有关闭它。 2)然后您通过上下文管理器以正确的方式打开文件,实际上可以从中读取任何内容。

一些可能有助于您调试问题的问题:

  • 您打开的文件是否存储在网络资源中? (CIFS、NFS 等)
  • 您是否检查过文件未被其他进程打开? lsof 可以帮助您检查。
  • 这是在 Windows 还是 Linux 上运行的?如果它发生在 Windows 中,你可以在 linux 下测试吗?反之亦然?

我忘了提到你不应该将 CSV 用于与 Excel 相关的任何内容,即使文件似乎是 CSV 数据。使用 XLRD 模块 (https://pypi.python.org/pypi/xlrd) ,它是跨平台的,并且从 0.8 版本开始可以完美地打开和读取 XSL 和 XSLX 文件。

这段小代码将向您展示如何打开工作簿并以基本方式对其进行解析:

import xlrd  

def open_excel():  
  with xlrd.open_workbook('FFA.xlsx') as wb:  
      sh = wb.sheet_by_name('Sheet1')  
      for rownum in xrange(sh.nrows):  
        [Do whatever you need here]  

【讨论】:

  • 好吧,我在 Windows 中进行操作,我第一次打开它的主要原因是出于调试目的,以查看不在正常代码中的空字节。我最初也没有遇到这个问题。不,我无法在 Linux 中进行测试。需要指出的是,在转换为 .csv 文件后,字节更改为 'playerId,playername,position,team,points,overallECR,overallRank,positionRank,up‌​per,lower,risk,swing\r\n100029,49ers ,DST,SF,104.896,245,979,16,165.7802,92.0755,4‌​.0319,73.7047\r\n2543501,Aaron Colvin,DB,JAC' 这意味着 \r\n 是在一个根本没有数据的单元格中生成的。
  • 请看我的评论,因为我编辑了我的答案;尝试使用 xlrd,它应该可以立即工作。
  • 那么必须输入什么才能使用 xlrd 打开文件?
  • 下面的示例仅涵盖您关于打开文件 xlrd.h 的问题。有关更多信息,请查看文档 (secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/…) 或在 StackOverflow 中搜索此处,有很多关于使用它的问题和答案。我已在原始答案中添加了示例。
  • 好的,所以它打印行号我如何访问行中的值?
【解决方案2】:

所以这就是我所做的。但我对学习 xlrd 方法很感兴趣,我有模块但没有文档。这没有错误消息。仍然不确定为什么它从 .csv 更改为 xlsx 但它现在可以工作了。 xlrd 中的脚本是什么样的?

import csv
def readFile():
    count = 0
    #print repr(open("FFA.csv", "rb").read(200)) #dump 1st 200 bytes check if null values produced.
    with open("FFA.csv","rb") as csvfile:
        FFAreader = csv.reader(csvfile, delimiter=",")
        for row in FFAreader:
            idd = row[0]
            name = row[1]
            pos = row[2]
            team = row[3]
            pts = row[4]
            oecr = row[5]
            oR = row[6]
            posR = row[7]
            up = row[8]
            low =row[9]
            risk = row[10]
            swing = row[11]
readFile()

【讨论】:

【解决方案3】:

我同意 Marc 的观点,我做了一个导入 excel 文件的培训练习,我认为 pandas 库在这种情况下会有所帮助,您可以将 pandas 作为 pd 导入并使用 pd.read_excel(file_name) 作为 read_file 等数据处理函数的一部分() 导入后。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    相关资源
    最近更新 更多