我需要从平面文件中读取记录,其中每个128字节构成一个逻辑记录。下面的这个阅读器的调用模块只是做以下事情。如何重构此IO代码?
while(iterator.hasNext()){
iterator.next();
//do Something
}
意味着将有每hasNext()
调用后next()
电话。
现在,这里是读者。
public class FlatFileiteratorReader implements Iterable<String> {
FileChannel fileChannel;
public FlatFileiteratorReader(FileInputStream fileInputStream) {
fileChannel = fileInputStream.getChannel();
}
private class SampleFileIterator implements Iterator<String> {
Charset charset = Charset.forName("ISO-8859-1");
ByteBuffer byteBuffer = MappedByteBuffer.allocateDirect(128 * 100);
LinkedList<String> recordCollection = new LinkedList<String>();
String record = null;
@Override
public boolean hasNext() {
if (!recordCollection.isEmpty()) {
record = recordCollection.poll();
return true;
} else {
try {
int numberOfBytes = fileChannel.read(byteBuffer);
if (numberOfBytes > 0) {
byteBuffer.rewind();
loadRecordsIntoCollection(charset.decode(byteBuffer)
.toString().substring(0, numberOfBytes),
numberOfBytes);
byteBuffer.flip();
record = recordCollection.poll();
return true;
}
} catch (IOException e) {
// Report Exception. Real exception logging code in place
}
}
try {
fileChannel.close();
} catch (IOException e) {
// TODO Report Exception. Logging
}
return false;
}
@Override
public String next() {
return record;
}
@Override
public void remove() {
// NOT required
}
/**
*
* @param records
* @param length
*/
private void loadRecordsIntoCollection(String records, int length) {
int numberOfRecords = length/128;
for (int i = 0; i < numberOfRecords; i++) {
recordCollection.add(records.substring(i * 128, (i + 1) * 128));
}
}
}
@Override
public Iterator<String> iterator() {
return new SampleFileIterator();
}
}
该代码读取机上80 MB 1.2秒内的数据与7200转HDD,与Sun JVM和运行Windows XP操作系统。但是我对我写的代码并不满意。有没有其他方法可以更好地编写它(特别是对字符集进行解码,并只读取已读取的字节,我的意思是charset.decode(byteBuffer) .toString().substring(0, numberOfBytes)
部分,请忽略//TODO
的东西)?
对于http://codereview.stackexchange.com,这可能是一个更好的问题。 –
我同意马特,这应该是codereview。当你发布它时,确保你包含了你不满意的内容。 –
@Matt Ball我害怕我能否在那里得到更好的答案。如果给出一个选项,我希望问题在这里。 – nobody