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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/442188/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:07:59  来源:igfitidea点击:

ReadInt(), ReadByte(), ReadString(), etc. in Python?

python

提问by ryeguy

The functions ReadInt(), ReadByte(), and ReadString() (to name a few) exist in other languages for reading input from streams. I am trying to read from a socket, and I want to use functions like these. Are they tucked away in Python somewhere under a different way or has someone made a library for it?

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

Also, there are Writedatatype() counterparts.

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

回答by Moshe Revah

Python's way is using struct.unpack to read binary data. I'm very used to the BinaryReader and BinaryWriter in C#, so I made this:

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]

Once you have a stream, you put it in the BinaryStream constructor and you got a BinaryStream :)

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

Example:

例子:

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()

回答by Swaroop C H

I think struct.unpack_fromis what you're looking for.

我认为struct.unpack_from是你要找的。

回答by Thierry G.

I used the code of Zippoxer and it works well for almost everything, thank you.

我使用了 Zipboxer 的代码,它几乎适用于所有情况,谢谢。

However I had some issue with readString(). It was specified in the C# doc that the length is encoded on 7 bytes. Thus I used readUChar instead of readUInt16:

但是我对 readString() 有一些问题。在 C# 文档中指定长度编码为 7 个字节。因此我使用了 readUChar 而不是 readUInt16:

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

and it works now. Maybe it is specific to my problem ? But it may help someone...

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

回答by S.Lott

Note that Python doesn't have readByte, readInt and readString because it doesn't work directly with all those fancy data types. Files provides strings which you can convert.

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

Python <=2.6 has String and that's what you get from your input streams -- strings. The simple socket.read()provides this input. You can use structto convert the stream into a sequence of integers. What's important is that the pack and unpack conversions may be by byte, word, long, or whatever, but the Python result is integers.

Python <=2.6 有字符串,这就是你从输入流中得到的——字符串。简单socket.read()提供了这个输入。您可以使用struct将流转换为整数序列。重要的是打包和解包转换可以按字节、字、长或其他方式进行,但 Python 结果是整数。

So your input may be bytes, but Python represents this as a string, much of which is unprintable. Your desire may be an array of individual values, each between 0 and 255, that are the numeric versions of those bytes. Python represents these as integers.

所以你的输入可能是字节,但 Python 将其表示为一个字符串,其中大部分是不可打印的。您想要的可能是单个值的数组,每个值都在 0 到 255 之间,它们是这些字节的数字版本。Python 将这些表示为整数。

Python >=3.0 has bytearrays that can be used to process bytes directly. You'll can convert them to strings, or integers (which include bytes and longs) or whatever.

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