Java 向加载到内存中的文件追加字符的最快/最有效的方法是什么?

Java 向加载到内存中的文件追加字符的最快/最有效的方法是什么?,java,file-io,java.util.scanner,Java,File Io,Java.util.scanner,我试图做的是,将整个.txt文件读入一个字符串,并在字符串中添加一个换行符。然后通过传递data_buffer.toString()创建一个新的扫描器来处理这个字符串。显然,对于非常大的文件,这个过程会占用很多时间,我只想在已读入内存的.txt文件中添加一个换行符 我知道整个想法似乎有点老套或怪异,但有没有更快的方法 干杯:)做某事最快的方法往往是根本不做 为什么不修改解析代码,使末尾的换行符不再是必需的?如果您每次都要添加它,那么您也可以更改代码的行为,使其看起来好像它在那里,而实际上它并不在

我试图做的是,将整个.txt文件读入一个字符串,并在字符串中添加一个换行符。然后通过传递data_buffer.toString()创建一个新的扫描器来处理这个字符串。显然,对于非常大的文件,这个过程会占用很多时间,我只想在已读入内存的.txt文件中添加一个换行符

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


干杯:)

做某事最快的方法往往是根本不做

为什么不修改解析代码,使末尾的换行符不再是必需的?如果您每次都要添加它,那么您也可以更改代码的行为,使其看起来好像它在那里,而实际上它并不在那里

接下来,我将尝试避免逐字符创建一个巨大的字符串,因为这确实是相当昂贵的。您可以基于
输入流
创建
扫描仪
,它可能比将数据读入
字符串
并对其进行解析快得多。您可以重写
FileInputStream
,在文件末尾返回一个虚拟换行符,从而避免粘贴字符串的出现


如果您确实必须将数据读入缓冲区,那么最好使用流中基于数组的
read()
方法读入字节数组,这比逐字节读入快得多。因为您可以预先知道文件的大小,所以可以为额外的行尾标记分配缓冲区空间,并将其插入数组中。与创建
StringBuffer
并从中生成
String
不同,这不需要缓冲区的完整副本。

做某事的最快方法通常是根本不做

为什么不修改解析代码,使末尾的换行符不再是必需的?如果您每次都要添加它,那么您也可以更改代码的行为,使其看起来好像它在那里,而实际上它并不在那里

接下来,我将尝试避免逐字符创建一个巨大的字符串,因为这确实是相当昂贵的。您可以基于
输入流
创建
扫描仪
,它可能比将数据读入
字符串
并对其进行解析快得多。您可以重写
FileInputStream
,在文件末尾返回一个虚拟换行符,从而避免粘贴字符串的出现


如果您确实必须将数据读入缓冲区,那么最好使用流中基于数组的
read()
方法读入字节数组,这比逐字节读入快得多。因为您可以预先知道文件的大小,所以可以为额外的行尾标记分配缓冲区空间,并将其插入数组中。与创建
StringBuffer
并从中生成
String
不同,这不需要缓冲区的完整副本。

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

以下是一个示例(未经测试):

这只读取文件一次,从不复制它(与StringBuffer不同——除非您确实需要同步StringBuffer,否则您应该使用StringBuilder)


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

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

以下是一个示例(未经测试):

这只读取文件一次,从不复制它(与StringBuffer不同——除非您确实需要同步StringBuffer,否则您应该使用StringBuilder)


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

据我所知,您实际要做的是以这样的方式读取文件,即文件在最后一行的末尾似乎总是有一个行分隔符

如果是这种情况,那么您可以通过实现一个子类型
FilterReader
,并在到达字符流末尾时,根据需要让它“插入”一个或两个额外的字符来实现这一点


执行此操作的代码不会很琐碎,但它将避免在内存中缓冲整个文件的时间和空间开销。

据我所知,您实际要做的是以这样一种方式读取文件,即文件在最后一行的末尾似乎总是有一个行分隔符

如果是这种情况,那么您可以通过实现一个子类型
FilterReader
,并在到达字符流末尾时,根据需要让它“插入”一个或两个额外的字符来实现这一点


执行此操作的代码不会很琐碎,但它将避免在内存中缓冲整个文件的时间和空间开销。

至少,将StringBuffer初始化为文件的长度(如果您知道的话),或者至少初始化为一个合理的大数,以最小化重新分配操作。谢谢。我发现这个链接也很好地发挥了作用,所以对于那些碰巧和我有同样想法的人来说:好吧,至少,将StringBuffer初始化为文件的长度(如果你知道的话),或者至少初始化为一个相当大的数,以最小化重新分配操作。谢谢。我发现这个链接也很好地发挥了作用,所以对于那些碰巧对我有同样想法的人来说:
    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"));
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;
    }
}