如何在Java

时间:2017-02-06 20:54:55

标签: java indexing

我有这个大文件,格式如下:

唯一字符串 \t 信息

在我的程序中,我需要阅读此文件,以通过唯一字符串键获取信息。由于性能很重要,我不能每次都读取每一行寻找密钥,除了我无法将文件加载到内存中,因为它太重了。然后我只想读取文件一次,然后使用String键和文件中的位置(以字节为单位)构建索引。该索引类似于HashMap,其键是唯一字符串,值是文件中出现键的字节。

似乎RandomAccessFile可以做到这一点,但我不知道如何。

那么,如何构建此索引,然后通过此索引访问特定行?

2 个答案:

答案 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