バイナリファイルから大量のバイトを読み取っています。RARファイルです。ヘッダーの仕様に次のように記載されているため、ファイルの 11 番目と 12 番目のバイトに興味があります。
HEAD_FLAGS ビットフラグ: 2 バイト
0x0001 - Volume attribute (archive volume) 0x0002 - Archive comment present RAR 3.x uses the separate comment block and does not set this flag. 0x0004 - Archive lock attribute 0x0008 - Solid attribute (solid archive) 0x0010 - New volume naming scheme ('volname.partN.rar') 0x0020 - Authenticity information present RAR 3.x does not set this flag. 0x0040 - Recovery record present 0x0080 - Block headers are encrypted 0x0100 - First volume (set only by RAR 3.0 and later) other bits in HEAD_FLAGS are reserved for internal use
私が遊んでいるファイルには00
、0D
それぞれ位置 11 と 12 があります。
これら 2 つの値はビット フラグであるため、意味がわかりません (理解できませんでした)。
これら 2 つの値は、byte
長さが 12 バイトの配列に含まれています。このシーケンスで確認する必要があるのは、フラグ0x0100
と0x0001
が設定されているかどうかです。
私はこれで迷っています。ありがとう。
Hex エディターでいくつかのファイルを調べたところ、11 番目と 12 番目のバイトを一緒に読み取る必要があることがわかりました。そのため、仕様ではすべてのビット フラグが 4 文字の 16 進数コードであると記載されています。ビット フラグを個別にチェックすると、正しくない結果が得られます。
回答/ヒントからできるだけ多くの情報を吸収して、次の方法でこれを解決しました:
FileInputStream fisFileInputStream = new FileInputStream((new File("C:\\testarchive.r00"));
byte[] bytHeader = new byte[20]; //The first 20 bytes are the RAR header.
fisFileInputStream.read(bytHeader);
short val=(short)( ((bytHeader[10]&0xFF)<<8) | (bytHeader[11]&0xFF) ); //Joining the two bytes into a short
System.out.println("Volume Attribute (0x0001): " + ((val & 0x0001) != 0));
System.out.println("First volume (0x0100): " + ((val & 0x0100) != 0));
複数の RAR アーカイブでこのコードを試しました — スパンされたアーカイブ、スパンされていないアーカイブ、スパンされたアーカイブの最初のファイル、スパンされたアーカイブの別のファイル。
コード自体は、非常に小さな癖を除いて正常に動作します。16進値から反対の結果が得られます。つまり
スパン アーカイブ内の最初のファイルではないファイルを検査すると、ボリューム属性0x0001
が設定されていない ( false
) と表示され、「最初のボリューム」0x100
が設定されている ( true
) と表示されます。
スパン アーカイブの最初のファイルを検査すると、正反対の結果が得られます。
ここで、元の仕様が間違っている (可能性は非常に低い) と信じるようにコードを変更します。これは、これ0x0001
がスパン アーカイブの最初のファイルであり、スパン アーカイブであることを0x0100
意味します。
..しかし、ビットフラグロジックで何か間違っていると思います。何か案は?