次のコードを検討してください。
private File readFromFile1(File file1) {
int offset = 0;
long message = 0;
File file2 = null;
try {
FileInputStream fis = new FileInputStream(file1);
byte[] data = new byte[8]; //Read buffer
byte[] tmpbuf = new byte[8]; //Temporary chunk buffer
file2 = new File("file2.txt");
FileOutputStream fos = new FileOutputStream(file2.getAbsolutePath(), true);
DataOutputStream dos = new DataOutputStream(fos);
int readcnt; //Read count
int chunk; //Chunk size to write to tmpbuf
while ((readcnt = fis.read(data, 0, 8)) != -1) {
//// POINT A ////
//Skip chunking system if an 8 byte octet is read directly.
if(readcnt == 8 && offset == 0){
message = someOperation(tmpbuf); // operation according to business logic
dos.writeLong(message);
continue;
}
//// POINT B ////
chunk = Math.min(tmpbuf.length - offset, readcnt); //Determine how much to add to the temp buf.
System.arraycopy(data, 0, tmpbuf, offset, chunk); //Copy bytes to temp buf
offset = offset + chunk; //Sets the offset to temp buf
if (offset == 8) {
message = someOperation(tmpbuf); // operation according to business logic
dos.writeLong(message);
if (chunk < readcnt) {
System.arraycopy(data, chunk, tmpbuf, 0, readcnt - chunk);
offset = readcnt - chunk;
} else {
offset = 0;
}
}
}
//// POINT C ////
//Process remaining bytes here...
//message = foo(tmpbuf);
//dos.writeLong(message);
fos.close();
dos.close();
fis.close();
} catch (IOException e) {
System.out.println("Some error occurred while reading from File:" + e);
}
return file2;
}
このコードの抜粋で、私がしたことは次のとおりです。
- 読み取りコードを変更して、read() メソッドから実際に読み取ったバイト数を含めます (readcnt と記述)。
- バイト チャンク システムを追加しました (チャンク バッファに少なくとも 8 バイトが存在するまで処理は行われません)。
- 最終バイト (8 バイトのオクテットを構成しない) を個別に処理できます。
コードからわかるように、読み取られるデータは、少なくとも 8 バイトが使用可能になるまで、最初にチャンキング バッファー (tmpbuf で示されます) に格納されます。これは、8 バイトが常に使用可能であるとは限らない場合にのみ発生します (8 バイトが直接使用可能で、何もチャンクされていない場合は、直接処理します。コードの「ポイント A」を参照してください)。これは、過剰な配列のコピーを防ぐための最適化の形式として行われます。
チャンキング システムは、値が 8 に達するまでバイトが tmpbuf に書き込まれるたびに増加するオフセットを使用します (「チャンク」の割り当てで使用される Math.min() メソッドが値を制限するため、それを超えることはありません)。オフセット == 8 で、処理コードの実行に進みます。
その特定の読み取りで実際に処理されたよりも多くのバイトが生成された場合は、オフセットを適切に設定しながら、最初から tmpbuf への書き込みを続行します。それ以外の場合は、オフセットを 0 に設定します。
サイクルを繰り返します。
コードは、実際に書き込まれた量を示すオフセット変数を使用して、配列 tmpbuf のオクテットに収まらないデータの最後の数バイトを残します。このデータは、ポイント C で個別に処理できます。
本来よりもはるかに複雑に思えますが、おそらくより良い解決策があります (おそらく既存の Java ライブラリ メソッドを使用します)。これが理解できるほど明確であることを願っています。