【问题标题】:Read file from sys.stdin in 'rb' mode : Python以“rb”模式从 sys.stdin 读取文件:Python
【发布时间】:2020-03-12 04:33:25
【问题描述】:

我已经编写了以下代码来将 csv 文件转换为 xml 文件。我正在从 sys.stdin 读取文件并将输出写回 sys.stdout。读取文件时出现以下错误。

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcc in position 7652: invalid continuation byte

我研究了错误,发现以“rb”模式读取输入文件可能会解决错误。现在如何更改以下代码以在“rb”模式下从 sys.stdin 读取输入文件。我还没有找到答案。

import csv
import sys
import os
from xml.dom.minidom import Document

filename = sys.argv[1]
filename = os.path.splitext(filename)[0]+'.xml'
pathname = "/tmp/"
output_file = pathname + filename

f = sys.stdin
reader = csv.reader(f)
fields = next(reader)
fields = [x.lower() for x in fields]
fieldsR = fields

doc = Document()
dataRoot = doc.createElement("rowset")
dataRoot.setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance")
dataRoot.setAttribute('xsi:schemaLocation', "./schema.xsd")
doc.appendChild(dataRoot)

for line in reader:
    dataElt = doc.createElement("row")           
    for i in range(len(fieldsR)):
        dataElt.setAttribute(fieldsR[i], line[i])
        dataRoot.appendChild(dataElt)


xmlFile = open(output_file,'w')
xmlFile.write(doc.toprettyxml(indent = '\t'))
xmlFile.close()
sys.stdout.write(output_file)

【问题讨论】:

  • 这是 Python 2 还是 Python 3 代码?如果是 Python 3,切换到二进制模式很容易,但也不是答案; csv 模块需要 str 输入。
  • 它是 Python 3。输入是通过 sys.stdin 的普通 csv 文件。其中有文本数据而不是二进制数据。能否请您详细说明如何在代码中解决它。
  • 问题不在于代码,而在于您的输入或您的语言环境。您的语言环境设置说输入应为 UTF-8;传递给sys.stdin 的实际数据采用其他编码(无法从错误中得知;类 UNIX 上的file 命令行实用程序可能能够告诉您数据是否从盘)。语言环境编码和文件编码需要一致,这样原始字节才能被解码为它们应该表示的逻辑文本。

标签: python unicode


【解决方案1】:

在 Python 3 中,stdin、stout 和 stderr 都包装在 IO 缓冲区中,这些缓冲区将动态文本编码/解码应用于流。

如果您想直接访问底层二进制流,它可以作为这些包装器中的属性使用。

对于标准输入,而不是在sys.stdin 中调用.read 执行sys.stdin.buffer.raw.read() - (同样对于 stderr 和 stdout,只需使用 ...buffer.raw 即可获取底层二进制流)。

【讨论】:

    猜你喜欢
    • 2021-04-22
    • 1970-01-01
    • 2014-03-05
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 2022-12-07
    相关资源
    最近更新 更多