考虑以下代码:
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 字节八位字节)。
从代码中可以看出,正在读取的数据首先存储在分块缓冲区(表示为 tmpbuf)中,直到至少有 8 个字节可用。仅当 8 个字节不总是可用时才会发生这种情况(如果 8 个字节直接可用并且没有分块,则直接处理。参见代码中的“点 A”)。这是作为一种优化形式来完成的,以防止过多的数组副本。
分块系统使用每次将字节写入 tmpbuf 时递增的偏移量,直到它达到值 8(它不会继续,因为分配“块”时使用的 Math.min() 方法会限制该值)。在偏移量 == 8 时,继续执行处理代码。
如果该特定读取产生的字节多于实际处理的字节,则继续将它们从头开始写入 tmpbuf,同时适当地设置偏移量,否则将偏移量设置为 0。
重复循环。
代码会将最后几个字节的数据留在数组 tmpbuf 中的一个八位字节中,其中偏移变量指示实际写入了多少。然后可以在 C 点单独处理这些数据。
似乎比它应该的要复杂得多,并且可能有一个更好的解决方案(可能使用现有的 java 库方法),但在我脑海中,这就是我得到的。希望这足够清楚,您可以理解。