5

我正在尝试使用 Java 将文本文件输出到控制台。我想知道这样做最有效的方法是什么?

我研究了几种方法,但是很难辨别哪个是对性能影响最小的解决方案。

将文本文件输出到控制台将涉及读取文件中的每一行,然后将其写入控制台。

是否更好地使用:

  1. 带有 FileReader 的缓冲读取器,读取行并执行一堆 system.out.println 调用?

    BufferedReader in = new BufferedReader(new FileReader("C:\\logs\\")); 
    while (in.readLine() != null) {
          System.out.println(blah blah blah);          
    }         
    in.close();
    
  2. 扫描仪读取文件中的每一行并进行 system.print 调用?

    while (scanner.hasNextLine()) { 
        System.out.println(blah blah blah);   
    }
    

谢谢。

4

6 回答 6

5

如果您只想将文件的内容(并且不想打印下一个 int/double/etc.)打印到控制台,那么 aBufferedReader就可以了。

但是,您的代码不会产生您想要的结果。试试这个:

BufferedReader in = new BufferedReader(new FileReader("C:\\logs\\log001.txt"));
String line = in.readLine();
while(line != null)
{
  System.out.println(line);
  line = in.readLine();
}
in.close();

不过,我不会对此过于挂念,因为主要瓶颈更有可能是控制台打印 Java 发送的信息的能力。

于 2010-10-07T22:21:14.240 回答
4

如果您对文本文件包含的基于字符的数据不感兴趣,只需将其“原始”作为字节流式传输。

InputStream input = new BufferedInputStream(new FileInputStream("C:/logs.txt"));
byte[] buffer = new byte[8192];

try {
    for (int length = 0; (length = input.read(buffer)) != -1;) {
        System.out.write(buffer, 0, length);
    }
} finally {
    input.close();
}

这节省了在字节和字符之间进行不必要的按摩以及扫描和分割换行符并再次附加它们的成本。

至于性能,您可能会发现这篇文章很有趣。根据文章,aFileChannel具有 256K 字节数组,通过包装ByteBuffer直接从字节数组中读取和写入是最快的方法。

FileInputStream input = new FileInputStream("C:/logs.txt");
FileChannel channel = input.getChannel();
byte[] buffer = new byte[256 * 1024];
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);

try {
    for (int length = 0; (length = channel.read(byteBuffer)) != -1;) {
        System.out.write(buffer, 0, length);
        byteBuffer.clear();
    }
} finally {
    input.close();
}
于 2010-10-07T22:27:33.137 回答
3

如果它是一个相对较小的文件,那么执行此操作的单行 Java 7+ 方法是:

System.out.println(new String(Files.readAllBytes(Paths.get("logs.txt"))));

有关更多详细信息,请参阅https://docs.oracle.com/javase/7/docs/api/java/nio/file/package-summary.html

干杯!

于 2016-09-21T00:44:50.043 回答
2

如果您想要的只是最有效地将文件内容转储到控制台而不进行中间处理,则将数据转换为字符并查找换行符是不必要的开销。相反,您可以从文件中读取字节块,然后直接写入System.out

package toconsole;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

public class Main {
    public static void main(String[] args) {
        BufferedInputStream bis = null;
        byte[] buffer = new byte[8192];
        int bytesRead = 0;
        try {
            bis = new BufferedInputStream(new FileInputStream(args[0]));
            while ((bytesRead = bis.read(buffer)) != -1) {
                System.out.write(buffer, /* start */ 0, /* length */ bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try { bis.close(); } catch (Exception e) { /* meh */ }
        }
    }
}

如果您以前没有遇到过这种习语,while 条件中的语句将 bis.read 的结果分配给 bytesRead,然后将其与 -1 进行比较。因此,我们一直将字节读入缓冲区,直到我们被告知我们在文件的末尾。我们在 System.out.write 中使用 bytesRead 来确保我们只写入刚刚读取的字节,因为我们不能假设所有文件的长度都是 8 kB 的倍数!

于 2010-10-07T22:29:18.937 回答
0
FileInputStream input = new FileInputStream("D:\\Java\\output.txt");
    FileChannel channel = input.getChannel();
    byte[] buffer = new byte[256 * 1024];
    ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); 

    try {
        for (int length = 0; (length = channel.read(byteBuffer)) != -1;) {
            System.out.write(buffer, 0, length);
            byteBuffer.clear();
        }
    } finally {
        input.close();
    }


    Path temp = Files.move 
            (Paths.get("D:\\\\Java\\\\output.txt"),  
            Paths.get("E:\\find\\output.txt")); 

            if(temp != null) 
            { 
                System.out.println("File renamed and moved successfully"); 
            } 
            else
            { 
                System.out.println("Failed to move the file"); 
            } 

}
于 2020-04-15T09:42:09.010 回答
0

对于Java 1 1,您可以使用更方便的方法:

Files.copy(Path.of("file.txt"), System.out);

或者为了更快的输出:

var out = new BufferedOutputStream(System.out);
Files.copy(Path.of("file.txt"), out);
out.flush();
于 2021-03-24T18:25:17.390 回答