2012-04-22 66 views
0
read_data = new BufferedReader(new FileReader(args[0])); 
    data_buffer = new StringBuffer(); 

    int i; 

    while(read_data.ready()) 
    {   
     while((i = read_data.read()) != -1) 
     { 
      data_buffer.append((char)i); 
     }   
    } 

    data_buffer.append(System.getProperty("line.separator")); 

我想要做的是,将整个.txt文件读入一个字符串并在字符串中添加一个换行符。然后可以通过传递data_buffer.toString()来创建一个新的扫描器来处理这个字符串。很明显,在真正大的文件中,这个过程需要花费很多时间,我所要做的只是在我读入内存的.txt文件中添加一个换行符。什么是最快/最有效的方式来追加一个文件加载到内存中的文件?

我知道整个想法似乎有点怪异或怪异,但有没有更快的方法?

干杯:)

+0

嗯,至少,初始化StringBuffer到文件的长度(如果你能知道的话)或者至少是一个相当大的数字,以最小化重新分配操作。 – 2012-04-22 14:33:35

+0

谢谢。我发现这个链接也做得非常好,所以对于碰巧想知道我是同一件事的其他人:http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner.html – Chrispy 2012-04-22 14:40:31

回答

3

做某事的最快方法通常是不要做。

为什么不修改解析代码,使得最后的换行符不是必需的?如果您每次都追加它,那么您可以更改代码,使其表现得好像在那里一样,而实际上并不存在。

接下来我想尝试的是避免通过char创建一个巨大的String char,因为这确实是相当昂贵的。您可以基于InputStream创建Scanner,它可能比将数据读入String并解析该数据要快得多。您可以覆盖您的FileInputStream以在文件末尾返回虚拟换行符,从而避免粘贴字符串的安装。

如果你绝对肯定必须将数据读入缓冲区,那么使用流的基于数组的read()读入字节数组可能会更好 - 比字节快得多。由于您可以事先知道文件的大小,因此可以为缓冲区分配足够的空间用于额外的行尾标记,并将其插入到数组中。与创建一个StringBuffer并将其作为String不同,这不需要缓冲区的完整副本。

1

如果您所做的只是将生成的文件传递给扫描仪,则应为该文件创建一个可读文件并将其发送给扫描仪。

下面是一个例子(未经测试):

public class NLReader implements Readable { 

    Reader r; 
    boolean atEndOfReader = false; 
    boolean atEnd = false; 

    public NLReader(Reader r) { 
     this.r = r; 
    } 

    public int read(CharBuffer cb) throws IOException { 
     if (!atEndOfReader) { 
      int result = r.read(cb); 
      if (result == -1) { 
       atEndOfReader = true; 
      } else { 
       return result; 
      } 
     } 
     if (!atEnd) { 
      String nl = System.getProperty("line.separator"); 
      cb.append(nl); 
      atEnd = true; 
      return nl.length(); 
     } 

     return -1; 
    } 
} 

这只能读取文件一次,并且从来没有把它复制(不像你的StringBuffer - 相反,除非你真的需要的StringBuffer同步,你应该使用StringBuilder的)。

这也不会将实际的文件加载到内存中,这样也可以节省内存压力。

2

从我所知道的是,你在做什么试图做的是以这样的方式读取文件,使得它总是在最后一行的末尾显示一个行分隔符。

如果是这种情况,那么你可以通过实现FilterReader的子类来实现,并在需要时插入一个或多个额外字符,当它到达字符流的末尾时。

执行此操作的代码不会变得无足轻重,但它将避免缓冲整个文件在内存中的时间和空间开销。

相关问题