ホームページ >バックエンド開発 >Python チュートリアル >Python でのパックとアンパックの使用法の概要
ファイルへのアクセスやソケット操作など、バイナリデータを処理するために Python を使用する必要がある場合があります。このとき、Python の struct モジュールを使用して C 言語で構造体を処理できます。
struct モジュール内の 3 つの最も重要な関数は、pack()、unpack()、calcsize() ですpack(fmt, v1, v2, ...) は、指定された形式 (fmt) に従ってデータをカプセル化します。 string (実際にはC構造に似たバイトストリームです)unpack(fmt, string) 指定された形式(fmt)に従ってバイトストリーム文字列を解析し、解析されたタプルを返しますcalcsize(fmt) 指定された数を計算しますformat (fmt) が占有するメモリのバイト数は次のとおりです: Format C 型 Python バイト数 x パッドバイト 値なし 1c 長さ 1 の char 文字列 1 b signed char integer 1B unsigned char integer 1? _Bool bool 1h short integer 2H unsigned short integer 2i int integer 4I unsigned int integer または long 4l long inティーガー4
L unsigned long long 4q long long long 8Q unsigned long long long 8f float float 4d double float 8s char[] string 1p char[] string 1
P void * long注 1.q と Q は、マシンが 64 ビット動作をサポートしている場合にのみ興味深いです注 2. 各形式の前に番号を示す数字を付けることができます注 3.s 形式は特定の長さの文字列を示し、4s は長さ 4 の文字列を表しますが、p はパスカル文字列を表します注 4。 P はポインタの変換に使用され、その長さはマシン語の長さに関連します注 5。最後の 1 つは、ポインター型を表すために使用され、4 バイトを占めます C の構造体とデータを交換するには、一部の C または C++ コンパイラーが、通常は 4 バイトの単位で 32 ビット システムのバイト アライメントを使用することも考慮する必要があります。なので、構造体はローカル マシンのバイト オーダーに従って変換されます。フォーマットの最初の文字を使用してアライメントを変更できます。定義は次のとおりです。バイト数 = 元のバイト数によるネイティブ標準標準< 元のバイト数によるビッグエンディアン標準標準!エンディアン) standard Press '@5s6sif' と同様に、fmt の最初の位置に元のバイト数が使用されます例 1: 構造は次のとおりです:
struct Header { unsigned short id; char[4] tag; unsigned int version; unsigned int count; }は上記の構造データを受け取りましたsocket.recv は文字列 s に存在します。今度はそれを解析する必要があります。unpack() 関数を使用できます。
import struct id, tag, version, count = struct.unpack("!H4s2I", s)上記の形式文字列では、 ! は解析にネットワーク バイト オーダーを使用することを意味します。データはネットワークからのものです。受信時、ネットワーク上で送信されるときはネットワーク バイト オーダーになります。次の H は符号なしの短い ID を表し、4s は 4 バイトの長さの文字列を表し、2I は 2 つの符号なし int 型データを表します。アンパックするだけで、情報が ID、タグ、バージョン、カウントに保存されました 同様に、ローカル データを構造体形式にパックすることも非常に便利です:
ss = struct.pack("!H4s2I", id, tag, version, count);Pack 関数は ID、タグ、バージョンを入れます。 、および count は、指定された形式に従ってヘッダー構造体に変換されます。ss は文字列 (実際には c 構造体に似たバイト ストリーム) になります。この文字列は、socket.send(ss) を通じて送信できます。 例2:
import struct a=12.34 #将a变为二进制 bytes=struct.pack('i',a)このとき、bytesは文字列stringであり、その文字列はバイト単位のaのバイナリ記憶内容と同じです。 次に、逆の操作を実行し、既存のバイナリ データ バイト (実際には文字列) を Python データ型に変換します: #unpack はタプルを返すことに注意してください!!
a,=struct.unpack('i',bytes)複数で構成されている場合は、次のように構成されますデータは次のようになります:
a='hello' b='world!' c=2 d=45.123 bytes=struct.pack('5s6sif',a,b,c,d)この時点のバイトはバイナリ形式のデータであり、binfile.write(bytes) などのファイルに直接書き込むことができますその後、必要なときに読み取ることができますそれを bytes=binfile .read() し、struct.unpack() を通じて Python 変数にデコードします。
a,b,c,d=struct.unpack('5s6sif',bytes)'5s6sif' は fmt と呼ばれ、数字と文字で構成される書式設定された文字列です。 5 文字の文字列。2i は 2 つの整数を意味します。使用可能な文字と型は次のとおりです。ctype は、Python の型に 1 対 1 で対応できることを意味します。 注: バイナリ ファイルの処理中に問題が発生しましたバイナリ ファイルを処理するときは、次のメソッドを使用する必要があります:
binfile=open(filepath,'rb') #读二进制文件 binfile=open(filepath,'wb') #写二进制文件それでは、binfile=open(filepath,'r') の結果の違いは何でしょうか? 2 つの違いがあります:
まず、「r」を使用するときに「0x1A」に遭遇すると、それはファイルの終わり、つまり EOF とみなされます。 「rb」を使用すると、この問題は発生しません。つまり、バイナリで書き込み、テキストで読み出す場合、「0X1A」が存在するとファイルの一部だけが読み出されます。 「rb」を使用すると、ファイルの最後まで読み取られます。
2 番目に、文字列 x=’abcndef’ の場合、len(x) を使用して長さを 7 にします。n を改行文字と呼び、実際には「0X0A」です。テキストモードである「w」で記述すると、「0X0A」は Windows プラットフォーム上で自動的に「0X0D」、「0X0A」の 2 文字に変更されます。つまり、実際のファイル長は 8 になります。 「r」テキスト モードで読み取ると、元の改行文字に自動的に変換されます。書き込み時に「wb」バイナリモードに変更すると、1文字は変更されず、読み取り時にそのまま読み込まれます。したがって、テキスト モードで書き込み、バイナリ モードで読み取る場合は、この余分なバイトを考慮する必要があります。 「0X0D」は復帰文字とも呼ばれます。 Linux では変化しません。 Linux は改行を表すために「0X0A」のみを使用するためです。
以上がPython でのパックとアンパックの使用法の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。