将 Unicode 流重新编码为 Ascii 忽略错误

2023-12-05

我正在尝试获取包含奇数字符的 Unicode 文件流,并用流读取器将其包装,将其转换为 Ascii,忽略或替换所有无法编码的字符。

我的流看起来像:

"EventId","Rate","Attribute1","Attribute2","(。・ω・。)ノ"
...

我尝试动态更改流的尝试如下所示:

import chardet, io, codecs

with open(self.csv_path, 'rb') as rawdata:
    detected = chardet.detect(rawdata.read(1000))

detectedEncoding = detected['encoding']
with io.open(self.csv_path, 'r', encoding=detectedEncoding) as csv_file:
    csv_ascii_stream = codecs.getreader('ascii')(csv_file, errors='ignore')
    log( csv_ascii_stream.read() )

结果在log线路是:UnicodeEncodeError: 'ascii' codec can't encode characters in position 36-40: ordinal not in range(128)即使我明确地构造了 StreamReadererrors='ignore'

我希望生成的流(读取时)如下所示:

"EventId","Rate","Attribute1","Attribute2","(?????)?"
...

或者,"EventId","Rate","Attribute1","Attribute2","()" (using 'ignore'代替'replace')

为什么会发生异常?

我见过很多解码字符串的问题/解决方案,但我的挑战是在读取流时更改流(使用.next()),因为文件可能太大而无法使用一次全部加载到内存中.read()


您混淆了编码和解码方面。

对于解码,你做得很好。您将其作为二进制数据打开,chardet第一个 1K,然后使用检测到的编码以文本模式重新打开。

但随后您尝试使用以下方法将已解码的数据进一步解码为 ASCIIcodecs.getreader。该函数返回一个StreamReader, which decodes来自流的数据。那是行不通的。你需要encode该数据转换为 ASCII。

但不清楚为什么你要使用codecs流解码器or首先,当您想要做的就是一次对单个文本块进行编码以便您可以记录它时。为什么不直接打电话给encode method?

log(csv_file.read().encode('ascii', 'ignore'))

如果你想要一些可以用作线的惰性迭代的东西,你could构建一些完全通用的东西,但是做类似的事情要简单得多UTF8Recorder中的示例csv docs:

class AsciiRecoder:
    def __init__(self, f, encoding):
        self.reader = codecs.getreader(encoding)(f)    
    def __iter__(self):
        return self
    def next(self):
        return self.reader.next().encode("ascii", "ignore")

或者,更简单地说:

with io.open(self.csv_path, 'r', encoding=detectedEncoding) as csv_file:
    csv_ascii_stream = (line.encode('ascii', 'ignore') for line in csv_file)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Unicode 流重新编码为 Ascii 忽略错误 的相关文章

随机推荐