生データのチャンクをファイルに保存し、後でそれらのチャンクを1つずつ読み取ります。これは、次の疑問を除いて大したことではありません。
区切り文字として、つまり1つのチャンクの終わりと次のチャンクの始まりを識別するために使用する正確なバイトはどれですか。チャンクデータにも、偶然にそのようなバイトシーケンスが含まれている可能性があることを前提としています。
注:チャンクは可変サイズであり、ランダムデータが含まれています。実はjpeg
画像です。
生データのチャンクをファイルに保存し、後でそれらのチャンクを1つずつ読み取ります。これは、次の疑問を除いて大したことではありません。
区切り文字として、つまり1つのチャンクの終わりと次のチャンクの始まりを識別するために使用する正確なバイトはどれですか。チャンクデータにも、偶然にそのようなバイトシーケンスが含まれている可能性があることを前提としています。
注:チャンクは可変サイズであり、ランダムデータが含まれています。実はjpeg
画像です。
最初にチャンクの長さを固定サイズの値 (4 バイト整数など) としてファイルに書き込み、その後にデータ自体を書き込むことができます。
public void appendChunk(byte[] data, File file) throws IOException {
DataOutputStream stream = null;
try {
stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file, true)));
stream.writeInt(data.length);
stream.write(data);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// ignore
}
}
}
}
後でそのファイルからチャンクを読み取る必要がある場合は、最初のチャンクの長さを読み取ることから始めます。チャンク データを読み取るか、スキップして次のチャンクに進むかを決定できるようになりました。
public void processChunks(File file) throws IOException {
DataInputStream stream = null;
try {
stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
while (true) {
try {
int length = stream.readInt();
byte[] data = new byte[length];
stream.readFully(data);
// todo: do something with the data
} catch (EOFException e) {
// end of file reached
break;
}
}
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// ignore
}
}
}
}
ファイルの元の名前を stream.writeUTF(...) で書き込むなど、チャンクに関する他のメタデータを追加することもできます。同じデータを同じ順序で読み書きすることだけを確認する必要があります。
チャンクのバイト範囲をチャンクファイルに保存する 2 番目のファイルを作成するか、その情報をチャンクファイルのヘッダーに追加します。似たようなことを一度しましたが、バイト範囲にはヘッダーの長さのオフセットが追加されていることを忘れないでください。
int startbyte = 0;
int lastByte = 0;
int chunkcount = 0;
File chunkfile;
File structurefile;
for (every chunk) {
append chunk to chunkfile
lastByte = startByte + chunk.sizeInBytes()
append to structurefile: chunkcount startByte lastByte
chunkcount++;
startByte = lastByte + 1
}