正如您所知,我们在java中有几个工具可以将数据写入流中
在这个示例代码中,我按运行时对它们进行了比较
有人能解释清楚吗?谢谢
这是代码:
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
public class IOtests
{
public static void main(String[] args) throws Exception
{
char[] chars = new char[100];
byte[] bytes = new byte[100];
for (int i = 0; i < 100; i++)
{
chars[i] = (char) i;
bytes[i] = (byte) i;
}
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(
"output.txt"));
long a = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
for (char j : chars)
out.write(j);
System.out.println("OutputStreamWriter writing characters: "
+ (System.currentTimeMillis() - a));
out = new OutputStreamWriter(new FileOutputStream("output.txt"));
a = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
for (byte j : bytes)
out.write(j);
System.out.println("OutputStreamWriter writing bytes: "
+ (System.currentTimeMillis() - a));
PrintStream out1 = new PrintStream("output.txt");
a = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
for (char j : chars)
out1.write(j);
System.out.println("PrintStream writing characters: "
+ (System.currentTimeMillis() - a));
out1 = new PrintStream("output.txt");
a = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
for (byte j : bytes)
out1.write(j);
System.out.println("PrintStream writing bytes: "
+ (System.currentTimeMillis() - a));
PrintWriter out2 = new PrintWriter("output.txt");
a = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
for (char j : chars)
out2.write(j);
System.out.println("PrintWriter writing characters: "
+ (System.currentTimeMillis() - a));
out1 = new PrintStream("output.txt");
a = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
for (byte j : bytes)
out2.write(j);
System.out.println("PrintWriter writing bytes: "
+ (System.currentTimeMillis() - a));
}
}
结果:
OutputStreamWriter写入字符:4141
OutputStreamWriter写入字节数:3546
PrintStream写入字符:86516
PrintStream写入字节数:70484
PrintWriter书写字符:938
PrintWriter写入字节数:2484
请注意,所有时间都以毫秒为单位。
我已经把你的问题归结为本质:
public class Test {
static byte[] bytes = new byte[10_000_000];
static {
for (int i = 0; i < bytes.length; i++) bytes[i] = (byte) (i%100+32);
}
public static void main(String[] args) throws Exception {
writer(true);
writer(false);
stream(true);
stream(false);
}
static void writer(boolean flush) throws IOException {
Writer out = new FileWriter("output.txt");
long a = System.currentTimeMillis();
for (byte j : bytes) {
out.write(j);
if (flush) out.flush();
}
out.close();
System.out.println("FileWriter with" + (flush? "":"out") + " flushing: " +
(System.currentTimeMillis() - a));
}
static void stream(boolean flush) throws IOException {
OutputStream out = new FileOutputStream("output.txt");
long a = System.currentTimeMillis();
for (byte j : bytes) {
out.write(j);
if (flush) out.flush();
}
out.close();
System.out.println("FileOutputStream with" + (flush? "":"out") + " flushing: " +
(System.currentTimeMillis() - a));
}
}
注:
- 完成后适当关闭资源
- 双循环被单循环取代,但数组更大
- 避免编写控制字符以避免自动刷新行为
- 只使用字节数组,因为在所有情况下只测试一种方法:
write(int)
。因此,无论您使用的是字节还是字符,都没有区别 - 删除了除
FileWriter
和FileOutputStream
之外的所有情况,因为所有其他情况都归结为这两种情况 - 以两种模式测试写入程序和输出流:每次写入后刷新,直到关闭才刷新
现在,当你运行这个程序时,你会得到如下输出:
FileWriter with flushing: 28235
FileWriter without flushing: 828
FileOutputStream with flushing: 23984
FileOutputStream without flushing: 23641
那么,教训是什么呢?
- 所有写入器都被缓冲,因为它们在内部委托给本身被缓冲的CCD_ 4
- CCD_ 5不被缓冲
- 非缓冲的逐字节写入非常慢
良好的实践要求始终执行缓冲写入:要么使用缓冲接收器,要么在您一侧维护显式缓冲区。