1

先做短版,后做长版:

短的 :

我有一个 float32 的二维矩阵。我想将它作为字节数组写入 .txt 文件。我还想保留结构,这意味着在行尾添加一个换行符。某些数字(例如 683.61)在转换为 bytearray 时包含 \n ,它会产生不需要的换行符并将文件读取为行。我怎样才能做到这一点?

长 :

我正在编写一个程序来处理大量数据(二维矩阵)。为此,我需要将阵列存储在磁盘上,而不是存储在我的 ram 上,因为数据对于计算机的 ram 来说可能太大了。我创建了自己的文件类型,该文件将被程序读取。它有一个带有重要参数的标头作为字节,然后是矩阵作为字节数组。

当我一次将数据写入一个 float32 的文件时,我在矩阵的一行末尾添加了一个换行符 (\n),因此我保留了结构。

写入顺利,但读取会导致问题,因为某些数字一旦转换为字节数组,就会包含 \n。

举个例子 :

struct.pack('f',683.61)

将产生

b'\n\xe7*D'

这会削减我的矩阵行,有时还会削减字节数组的中间,从而使字节数组的大小错误。

来自这个问题: Python 在写入文件时处理换行符和制表符

我发现 str 可以用 'unicode_escape' 编码以加倍反斜杠并避免阅读时混淆。

Some_string.encode('unicode_escape')

但是,此方法仅适用于字符串,而不适用于字节或字节数组。(我试过了)这意味着当我直接将float32转换为字节数组并将其写入文件时,我无法使用它。

我还尝试将浮点数转换为字节数组,将字节数组解码为 str 并像这样重新编码:

struct.pack('f',683.61).decode('utf-8').encode('unicode_escape')

但 decode 不能解码字节数组。

我也尝试将字节数组直接转换为字符串,然后像这样编码:

str(struct.pack('f',683.61)).encode('unicode_escape')

这会产生混乱,可以从中获得正确的字节:

bytes("b'\\n\\xe7*D'"[2:-1],'utf-8')

最后,当我实际读取字节数组时,无论是否使用了 unicode_escape ,我都会获得两个不同的结果:

numpy.frombuffer(b'\n\xe7*D', dtype=float32)
    yields : array([683.61], dtype=float32)

numpy.frombuffer(b'\\n\\xe7*D', dtype=float32)
    yields : array([1.7883495e+34, 6.8086554e+02], dtype=float32)

我期待最高的结果,而不是最低的结果。所以我回到第一方。

--> 如何将我的浮点矩阵编码为多行的字节数组,而不受字节数组中换行符的影响?

仅供参考,我用 numpy 解码字节数组,因为这是我找到的工作方法,但它可能不是最好的方法。刚开始玩字节。

谢谢你的帮助。如果我的问题有任何问题,请通知我,如果错误,我很乐意正确地重写它。

4

2 回答 2

2

您要么将数据写入二进制数据,要么使用换行符来保持可读性——否则它甚至没有意义。

当您尝试将“字节”记录到文件中并将 float32 原始值作为 4 字节序列时,每个字节当然可以具有 0-255 之间的任何值 - 其中一些将是控制字符。

替代方法是序列化为一种格式,该格式将使用协议 0 将您的字节值编码为可打印 ASCII 范围内的字符,例如 base64、Json 甚至 pickle。

也许对你来说最舒服的就是把你的原始字节写成二进制字节,然后改变你用来与之交互的程序——使用像“hexedit”或 Midnight Commander 这样的 hexeditor。两者都允许您以舒适的方式通过十六进制表示浏览字节,并将在文件中显示最终的 ASCII 文本序列。

于 2019-09-13T22:19:48.487 回答
0

对于任何与我有同样疑问的人,试图让 readline 函数与字节一起工作,@jsbueno 的先前回答让我想到了替代方法来继续而不是修改字节。

如果您像我一样使用数据作为字节制作自己的文件,这是另一种选择。根据经典的 read() 函数编写自己的 readline() 函数,但使用自定义的“换行符”。这是我的工作:

def readline(file, newline=b'Some_byte',size=None):
    buffer = bytearray()
    if size is None :
        while 1 :
            buffer += file.read(1)
            if buffer.endswith(newline):
                break
    else :
        while len(buffer) < size :
            buffer += file.read(1)
            if buffer.endswith(newline):
                break
    return buffer
于 2019-09-15T02:38:35.257 回答