我正在尝试使用Java将文本文件输出到控制台。我想知道最有效的方法是什么?
我研究过几种方法,但很难分辨哪种方法影响最小的解决方案。
将文本文件输出到控制台将涉及读取文件中的每一行,然后将其写入控制台。
使用是否更好:
带有FileReader的缓冲读取器,读取行并执行一系列system.out.println调用?
BufferedReader in = new BufferedReader(new FileReader("C:\\logs\\"));
while (in.readLine() != null) {
System.out.println(blah blah blah);
}
in.close();
扫描程序读取文件中的每一行并执行system.print调用?
while (scanner.hasNextLine()) {
System.out.println(blah blah blah);
}
感谢。
答案 0 :(得分: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();
}
这样可以节省不必要地按字节和字符进行按摩的成本,还可以扫描和拆分换行符并再次附加它们。
关于性能,您可能会发现this article很有趣。根据这篇文章,一个带有256K字节数组的FileChannel
是通过包装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();
}
答案 1 :(得分:3)
如果您只想打印文件的内容(并且不想将下一个int / double / etc打印到控制台),那么BufferedReader
就可以了。
但是,您的代码不会产生您所追求的结果。试试这个:
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发送信息的能力。
答案 2 :(得分: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长的倍数!
答案 3 :(得分:1)
如果它是一个相对较小的文件,那么单行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。
干杯!
答案 4 :(得分: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");
}
}
答案 5 :(得分:0)
对于 Java 11,您可以使用更方便的方法:
Files.copy(Path.of("file.txt"), System.out);
或者为了更快的输出:
var out = new BufferedOutputStream(System.out);
Files.copy(Path.of("file.txt"), out);
out.flush();