得到文件某行的偏移量(get byte offset of a line)
场景:通过对文件的一趟处理,把每行的offset得到。
现有的文件系统不能直接定位到某一行,如果你知道行号,也只能一行行的读下去,找到你想要的line。但是当文件很大的时候,就需要一定的预处理,保存行的offset,后续的处理可以根据offset直接定位到具体的line,无疑这会提高速度。所以需要实现:line到byte offset的映射。
Google了一番,没有发现可用的代码,但是思想是显而易见的:按字节顺序读取文件,然后读到行分割符的时候做相应处理,然而知易行难。
Read line by line
第一个想法是:每次读一行,然后行的长度可以用来更新offset,如下:
public void init() throws Exception {
// Scan the file to construct the data structure for use
file = new File(path);
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
entries = new Entry[this.lines()];
int k = 0;
int offset = 0;
while ((line = reader.readLine()) != null) {
line = line.replace("\"", "");
int len = line.length();
String cells[] = line.split(",");
int startIP = IPv4Util.ip2int(cells[0]);
int endIP = IPv4Util.ip2int(cells[1]);
//System.out.println("==" + startIP + "-" + endIP);
Entry entry = new Entry(startIP, endIP, offset);
entries[k++] = entry;
// NB.这里存在问题,因为offset是字节级别的,而字符串和特定编码有关
offset += len;
}
}
问题在于:字符串的编码是容易变动的,所以字节级别最通用。
Read byte by byte
每次读取一个字节,在遇到换行的时候我们根据读到的字节数更新offset,同时需要一个buffer保存此次读取到的line。
public void init2() throws Exception {
entries = new ArrayList<Entry>();
// Scan the file to construct the data structure for use
RandomAccessFile raf = new RandomAccessFile(path, "r");
byte buffer[] = new byte[1024]; //buf this current line
int b;
// raf.length();
int offset = 0;
int bytesRead = 0;
int bufferIndex = 0;
while((b = raf.read()) != -1){
// buffer it first
buffer[bufferIndex++] = (byte)b; // int to byte
bytesRead ++ ;
if(b == ‘\n‘){
String line = new String(buffer);
line = line.replace("\"", "");
//System.out.println(line);
int len = line.length();
String cells[] = line.split(",");
int startIP = IPv4Util.ip2int(cells[0]);
int endIP = IPv4Util.ip2int(cells[1]);
//System.out.println("==" + startIP + "-" + endIP + ", " + offset);
Entry entry = new Entry(startIP, endIP, offset);
entries.add(entry);
// reset
bufferIndex = 0;
Arrays.fill(buffer, (byte)0);
offset += bytesRead;// prepare offset for next entry
bytesRead = 0;
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-09 13:15:56