用Java解析txt文件的最快方法

时间:2015-04-30 09:09:56

标签: java parsing text

我必须解析具有以下形式的税务计算器的txt文件:

Name: Mary Jane
Age: 23
Status: Married
Receipts:

Id: 1
Place: Restaurant
Money Spent: 20

Id: 2
Place: Mall
Money Spent: 30

所以,到目前为止我所做的是:

public void read(File file) throws FileNotFoundException{
    Scanner scanner = new Scanner(file);
    String[] tokens = null;

    while(scanner.hasNext()){
        String line= scanner.nextLine();
        tokens = line.split(":");
        String lastToken = tokens[tokens.length - 1];
        System.out.println(lastToken);

所以,我想只访问这个档案的第二栏(Mary Jane,23岁,已婚)给班级纳税人(姓名,年龄,身份)和收据'信息给Arraylist。

我想把最后一个令牌保存到String数组中,但是我不能这样做,因为我不能将字符串保存到字符串数组中。有人能帮我吗?谢谢。

3 个答案:

答案 0 :(得分:1)

最快的方法是,如果您的数据是ASCII并且您不需要字符集转换,那就是使用BufferedInputStream并自己进行所有解析 - 找到行终止符,解析数字。不要使用Reader,或创建字符串,或每行创建任何对象,或使用parseInt。只需使用字节数组并查看字节。这有点麻烦,但是假装你正在编写C代码,它会更快。

还要考虑一下您创建的数据结构的紧凑程度,以及是否可以通过聪明的方式避免在每行创建一个对象。

答案 1 :(得分:0)

你真的需要它尽可能快吗?在这种情况下,创建一些对象并在此过程中进行一些垃圾收集通常很好,以便拥有更多可维护的代码。

我自己使用两个正则表达式(一个用于纳税人,另一个用于收据循环)。

我的代码看起来像:

public class ParsedFile {
    private Taxpayer taxpayer;
    private List<Receipt> receipts;

    // getters and setters etc.
}

public class FileParser {
    private static final Pattern TAXPAYER_PATTERN =
        // this pattern includes capturing groups in brackets ()
        Pattern.compile("Name: (.*?)\\s*Age: (.*?)\\s*Status: (.*?)\\s*Receipts:", Pattern.DOTALL);

    public ParsedFile parse(File file) {
        BufferedReader reader = new BufferedReader(new FileReader(file)));
        String firstChunk = getNextChunk(reader);
        Taxpayer taxpayer = parseTaxpayer(firstChunk);
        List<Receipt> receipts = new ArrayList<Receipt>();
        String chunk;
        while ((chunk = getNextChunk(reader)) != null) {
            receipts.add(parseReceipt(chunk));
        }
        return new ParsedFile(taxpayer, receipts);
    }

    private TaxPayer parseTaxPayer(String chunk) {
       Matcher matcher = TAXPAYER_PATTERN.matcher(chunk);
       if (!matcher.matches()) {
           throw new Exception(chunk + " does not match " + TAXPAYER_PATTERN.pattern());
       }
       // this is where we use the capturing groups from the regular expression
       return new TaxPayer(matcher.group(1), matcher.group(2), ...);
    }

    private Receipt parseReceipt(String chunk) {
       // TODO implement
    }

    private String getNextChunk(BufferedReader reader) {
       // keep reading lines until either a blank line or end of file
       // return the chunk as a string
    }
}

答案 2 :(得分:0)

首先,您为何需要将时间投入到最快的解决方案中?是因为输入文件很大吗?我也不明白你想如何存储解析结果?考虑新类,其中包含您需要从每个人的文件中提取的所有字段。

几点提示:   - 避免不必要的每行内存分配。代码中的line.split(":")就是这样的例子。   - 使用缓冲输入。   - 最小化输入/输出操作。

如果这些还不够,请尝试阅读本文http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly