我有这个大文件,格式如下:
唯一字符串 \t
信息
在我的程序中,我需要阅读此文件,以通过唯一字符串键获取信息。由于性能很重要,我不能每次都读取每一行寻找密钥,除了我无法将文件加载到内存中,因为它太重了。然后我只想读取文件一次,然后使用String键和文件中的位置(以字节为单位)构建索引。该索引类似于HashMap,其键是唯一字符串,值是文件中出现键的字节。
似乎RandomAccessFile可以做到这一点,但我不知道如何。
那么,如何构建此索引,然后通过此索引访问特定行?
答案 0 :(得分:2)
我建议的方法是阅读文件,并跟踪位置。沿着地图存放位置,以便以后查看。
第一种方法是将您的文件用作DataInput
,然后使用RandomAccessFile#readline
RandomAccessFile raf = new RandomAccessFile("filename.txt", "r");
Map<String, Long> index = new HashMap<>();
现在,您的数据是如何存储的?如果它是逐行存储的,并且ecoding符合DataInput
标准,那么您可以使用。
long start = raf.getFilePointer();
String line = raf.readLine();
String key = extractKeyFromLine(line);
index.put(key, start);
现在,只要您需要返回并获取数据。
long position = index.get(key);
raf.seek(position);
String line = raf.readLine();
这是一个完整的例子:
package helloworld;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;
/**
* Created by matt on 07/02/2017.
*/
public class IndexedFileAccess {
static String getKey(String line){
return line.split(":")[0];
}
public static void main(String[] args) throws IOException {
Map<String, Long> index = new HashMap<>();
RandomAccessFile file = new RandomAccessFile("junk.txt", "r");
//populate index and read file.
String s;
do{
long start = file.getFilePointer();
s = file.readLine();
if(s!=null){
String key = getKey(s);
index.put(key, start);
}
}while(s!=null);
for(String key: index.keySet()){
System.out.printf("key %s has a pos of %s\n", key, index.get(key));
file.seek(index.get(key));
System.out.println(file.readLine());
}
file.close();
}
}
junk.txt
包含:
dog:1, 2, 3 cat:4, 5, 6 zebra: p, z, t
最后输出是:
key zebra has a pos of 24 zebra: p, z, t key cat has a pos of 12 cat:4, 5, 6 key dog has a pos of 0 dog:1, 2, 3
这有很多警告。例如,如果您需要更强大的编码,那么在您第一次阅读时,您将需要创建一个可以管理编码的阅读器,并且只需使用RandomAccessFile
作为输入流。如果行太大,readLine()
方法将失败。然后你必须设计自己的策略来提取密钥/数据对。
答案 1 :(得分:1)
我需要阅读此文件以通过Unique获取信息 字符串键。
关于你的上述问题,你必须逐行阅读文件,使用@Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
getPayloadFromSoapMessage((SoapMessage) messageContext.getRequest());
}
protected String getPayloadFromSoapMessage(SoapMessage message) {
String payload = "Error parsing";
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
message.writeTo(bos);
payload = bos.toString();
} catch (IOException e) {
LOG.error("Error parsing the SoapMessage", e);
}
return payload;
}
拆分读取字符串,并将值放在split()
中,如下所示,
Map
现在,当您拥有try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
Map<String, int> map = new HashMap<String, int>();
int byte = 0;
while((line = bufferedReader.readLine()) != null) {
String arr[] = line.split("\t"); //make sure your file conatins data as you specified.
map.put(arr[0], byte);
byte += line.length() + 1;
}
bufferedReader.close();
}
catch(Exception ex) {
System.out.println("unable to open file '" + fileName + "'");
}
时,您可以访问任何information
,如下所示
specificString