linux java文件操作_Java文件操作类效率对比

前言

众所周知,Java中有多种针对文件的操作类,以面向字节流和字符流可分为两大类,这里以写入为例:

面向字节流的:FileOutputStream 和 BufferedOutputStream

面向字符流的:FileWriter 和 BufferedWriter

近年来发展出New I/O ,也叫NIO,里面又包装了两个类:NewOutputStream 和 NewBufferedWriter

现在,我们建立测试程序,比较这些类写入文件的性能。

机器配置

Processor Name: Intel Core i7

Processor Speed: 2.2 GHz

Number of Processors: 1

Total Number of Cores: 4

L2 Cache (per Core): 256 KB

L3 Cache: 6 MB

Memory: 16 GB

测试程序

纵向比较:几种文件操作类向文件中写入相同行数的内容(每行内容均为“写入文件Data\n”),比较其耗费时间

横向比较:对于同一个文件操作类,比较写入不同行数内容情况下所耗费时间;本文以2的次方指数级增长行数

import java.io.File;

import java.io.FileOutputStream;

import java.io.*;

import java.nio.file.Files;

import java.nio.file.Paths;

public class testFileIO {

public static void testDriver () throws IOException {

int maxlineNum = 100000001;//写入文件的最大行数

int startlineNum = 1;//写入文件的行数

int Multiplying = 2;//行数增长倍率

long begin = 0L;

long end = 0L;

//将时间统计写入文件Result.txt中

FileWriter fileWriter = new FileWriter("./Result.txt", true);

BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

System.out.println("Test FileOutputStream begin.");

for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {

begin = System.currentTimeMillis();

testFileOutputStream(lineNum);

end = System.currentTimeMillis();

long timeElapse_FileOutputStream = end - begin;

bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"\t");

}

System.out.println("Test FileOutputStream end.\n");

System.out.println("Test BufferedOutputStream begin.");

bufferedWriter.write("\n");

for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {

begin = System.currentTimeMillis();

testBufferedOutputStream(lineNum);

end = System.currentTimeMillis();

long timeElapse_BufferedOutputStream = end - begin;

bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"\t");

}

System.out.println("Test BufferedOutputStream end.\n");

System.out.println("Test FileWriter begin.");

bufferedWriter.write("\n");

for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {

begin = System.currentTimeMillis();

testFileWriter(lineNum);

end = System.currentTimeMillis();

long timeElapse_FileWriter = end - begin;

bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"\t");

}

System.out.println("Test FileWriter end.\n");

System.out.println("Test BufferedWriter begin.");

bufferedWriter.write("\n");

for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {

begin = System.currentTimeMillis();

testBufferedWriter(lineNum);

end = System.currentTimeMillis();

long timeElapse_BufferedWriter = end - begin;

bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"\t");

}

System.out.println("Test BufferedWriter end.\n");

System.out.println("Test NewOutputStream begin.");

bufferedWriter.write("\n");

for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {

begin = System.currentTimeMillis();

testNewOutputStream(lineNum);

end = System.currentTimeMillis();

long timeElapse_NewOutputStream = end - begin;

bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"\t");

}

System.out.println("Test NewOutputStream end.\n");

System.out.println("Test NewBufferedWriter begin.");

bufferedWriter.write("\n");

for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {

begin = System.currentTimeMillis();

testNewBufferedWriter(lineNum);

end = System.currentTimeMillis();

long timeElapse_NewBufferedWriter = end - begin;

bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"\t");

}

System.out.println("Test NewOutputStream end.\n");

bufferedWriter.close();

}

/************************** I/O *****************************/

//面向字节

public static void testFileOutputStream (int lineNum) throws IOException {

FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt"));

while (--lineNum > 0) {

fileOutputStream.write("写入文件Data\n".getBytes());

}

fileOutputStream.close();

}

public static void testBufferedOutputStream (int lineNum) throws IOException {

FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));

BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);

while (--lineNum > 0) {

bufferedOutputStream.write("写入文件Data\n".getBytes());

}

bufferedOutputStream.close();

}

//面向字符

public static void testFileWriter (int lineNum) throws IOException {

FileWriter fileWriter = new FileWriter("./testFileWriter.txt");

while (--lineNum > 0) {

fileWriter.write("写入文件Data\n");

}

fileWriter.close();

}

public static void testBufferedWriter (int lineNum) throws IOException {

FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");

BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

while (--lineNum > 0) {

bufferedWriter.write("写入文件Data\n");

}

bufferedWriter.close();

}

/************************** NIO ****************************/

public static void testNewOutputStream (int lineNum) throws IOException {

OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));

while (--lineNum > 0) {

outputStream.write("写入文件Data\n".getBytes());

}

outputStream.close();

}

public static void testNewBufferedWriter (int lineNum) throws IOException {

BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));

while (--lineNum > 0) {

newBufferedReader.write("写入文件Data\n");

}

newBufferedReader.close();

}

public static void main (String[] args) throws IOException {

//多次测试时可清空result.txt文件

FileWriter fileWriter = new FileWriter("./Result.txt");

testDriver();

}

}

测试结果

9588a63ec95538ad866f271a2f6119c2.png

从上图可以看出,写入行数超过20W以上时,FileOutputStream和NewOutputStream耗费时间远远超出其他4个类。为了清晰,让我们放大其他4个类的图:

331f61b798d48ad55d533e8e231d3340.png

可以看出,这4个类中,BufferWriter和NewBufferedWriter所耗费时间更少,但总体差别不是很大。

让我们再来看看,写入26W行数据以下时的情况:

03acf6583aa7d785d12b497828c65f4f.png

可以看出,在数据量较小的情况下,这4个类所耗费时间的差异并不是很大,在更小的数据量下,它们的效率几乎没有差别。

后记

从以上分析可知(注意横坐标写入行数是指数级增加的),各个类的时间复杂度大致为O(1/kn),其中不同的类的k不同,导致了最终巨大的差异。

这里只给出了测试结果,并未分析其底层实现原理,欢迎评论区留言。

另外,我没有在其他机器测试,有兴趣的小伙伴可以将自己的测试结果发出来,共同进步^_^

附件

本次测试数据结果(若看不清,可以下载到本地看)

d34feeda4cc29cd0c24cdf69683bbab8.png

0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值