Python中的ReadInt(),ReadByte(),ReadString()等?

时间:2009-01-14 07:34:05

标签: python

函数ReadInt(),ReadByte()和ReadString()(仅举几例)存在于其他语言中,用于从流中读取输入。我试图从套接字读取,我想使用这些函数。它们是以某种不同的方式隐藏在Python的某个地方,还是有人为它创建了一个库?

此外,还有Write 数据类型()对应项。

4 个答案:

答案 0 :(得分:10)

Python的方法是使用struct.unpack来读取二进制数据。 我很习惯C#中的BinaryReader和BinaryWriter,所以我做了这个:

from struct import *

class BinaryStream:
    def __init__(self, base_stream):
        self.base_stream = base_stream

    def readByte(self):
        return self.base_stream.read(1)

    def readBytes(self, length):
        return self.base_stream.read(length)

    def readChar(self):
        return self.unpack('b')

    def readUChar(self):
        return self.unpack('B')

    def readBool(self):
        return self.unpack('?')

    def readInt16(self):
        return self.unpack('h', 2)

    def readUInt16(self):
        return self.unpack('H', 2)

    def readInt32(self):
        return self.unpack('i', 4)

    def readUInt32(self):
        return self.unpack('I', 4)

    def readInt64(self):
        return self.unpack('q', 8)

    def readUInt64(self):
        return self.unpack('Q', 8)

    def readFloat(self):
        return self.unpack('f', 4)

    def readDouble(self):
        return self.unpack('d', 8)

    def readString(self):
        length = self.readUInt16()
        return self.unpack(str(length) + 's', length)

    def writeBytes(self, value):
        self.base_stream.write(value)

    def writeChar(self, value):
        self.pack('c', value)

    def writeUChar(self, value):
        self.pack('C', value)

    def writeBool(self, value):
        self.pack('?', value)

    def writeInt16(self, value):
        self.pack('h', value)

    def writeUInt16(self, value):
        self.pack('H', value)

    def writeInt32(self, value):
        self.pack('i', value)

    def writeUInt32(self, value):
        self.pack('I', value)

    def writeInt64(self, value):
        self.pack('q', value)

    def writeUInt64(self, value):
        self.pack('Q', value)

    def writeFloat(self, value):
        self.pack('f', value)

    def writeDouble(self, value):
        self.pack('d', value)

    def writeString(self, value):
        length = len(value)
        self.writeUInt16(length)
        self.pack(str(length) + 's', value)

    def pack(self, fmt, data):
        return self.writeBytes(pack(fmt, data))

    def unpack(self, fmt, length = 1):
        return unpack(fmt, self.readBytes(length))[0]

有了一个流,你把它放在BinaryStream构造函数中,你得到一个BinaryStream:)

示例:

from binary import BinaryStream

f = open("Users", "rb")
stream = BinaryStream(f)
users_count = stream.readUInt64()
for i in range(users_count):
    username = stream.readString()
    password = stream.readString()

答案 1 :(得分:8)

我认为struct.unpack_from正是您所寻找的。

答案 2 :(得分:1)

我使用了Zippoxer的代码,它适用于几乎所有的东西,谢谢。

但是我遇到了readString()的一些问题。在C#doc中指定长度以7个字节编码。因此我使用readUChar而不是readUInt16:

def readString(self):
    length = self.readUChar()
    return self.unpack(str(length) + 's', length)

现在可以使用了。也许它特定于我的问题?但它可能有助于某人...

答案 3 :(得分:0)

请注意,Python没有readByte,readInt和readString,因为它不能直接使用所有那些花哨的数据类型。文件提供了可以转换的字符串。

Python <= 2.6具有String,这是您从输入流中获得的 - 字符串。简单socket.read()提供此输入。您可以使用struct将流转换为整数序列。重要的是打包和解包转换可以是字节,字,长或其他,但Python结果是整数。

因此,您的输入可能是字节,但Python将其表示为字符串,其中大部分都是不可打印的。您的愿望可能是各个值的数组,每个值在0到255之间,即这些字节的数字版本。 Python将这些表示为整数。

Python >= 3.0具有可用于直接处理字节的字节数组。您可以将它们转换为字符串或整数(包括字节和长整数)或其他任何内容。