BufferedOutputStream与NIO写文件对比

本文通过一个Java程序展示了使用BufferedOutputStream和NIO进行文件写入的性能对比。程序创建了一个固定大小的线程池,分别执行10000次文件写入操作,记录并输出了两种方式的时间消耗。实验结果显示了两种方法在大量文件写入场景下的效率差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据内容(一行)如下所示

{"MAF":3.86,
"BASE_STATION":"1823,4207,460,0,37;18431,4207,460,0,25;1822,4207,460,0,25;",
"PID_010B":"",
"FUEL":10.49,
"REMARK":31922,
"MILAGE":18.94,
"PID_010C":"",
"PID_010F":"",
"RECEIVED_TIME":"2013-12-04 14:41:59",
"GATHERTIME":"2013-12-04 14:41:49",
"BABV":10.59,
"ACCSTATUS":"0",
"OBD_SPEED":145,
"G_FORCE":-0.49}


第一次:(磁盘非常卡)

名称文件数数据条数单条数据大小线程数耗时(s)备注
BufferedOutputStream1007200约310字节200611.557XP系统,4G内存,4核CPU、apache commons-io组件
FileChannel1007200约310字节200637.867XP系统,4G内存,4核CPU

第二次:(CPU 100%)

名称文件数数据条数单条数据大小线程数耗时(s)备注
BufferedOutputStream100007200约310字节2001963.642linux系统,2G内存,4核CPU
FileChannel100007200约310字节2001953.116linux系统,2G内存,4核CPU


代码:

package com.sides.file;

import java.io.File;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/****************************************************************************
* com.sides.file WriteFile.java Created on 2013-12-3
* @Author: linfenliang
* @Description:
* @Version: 1.0
***************************************************************************/
public class WriteFile {
/**
* @param args
* void
* @date 2013-12-3
* @version V1.0.0
* @author linfenliang
* @throws ExecutionException
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService service = Executors.newFixedThreadPool(200);
long t0 = System.nanoTime();
Future<Boolean> future = null;
for(int i=0;i<10000;i++){
WriterThread task = new WriterThread(DataFactory.dataList, String.format("/var/lib/log/nio/OBD_DATA%s.dat", i),true);
future = service.submit(task);
}
boolean b = future.get();
long t1 = System.nanoTime();
System.out.println(b+",time cost ms:"+(t1-t0)/1000000);

System.out.println("NIO is OK, ready to BufferedOutputStream write");
Thread.sleep(5*1000);

long t2 = System.nanoTime();
Future<Boolean> future2 = null;
for(int i=0;i<10000;i++){
WriterThread task = new WriterThread(DataFactory.dataList, String.format("/var/lib/log/buffer/OBD_DATA%s.dat",i),false);
future2 = service.submit(task);
}
boolean isOk = future2.get();
long t3 = System.nanoTime();
System.out.println(isOk+",time cost ms:"+(t3-t2)/1000000);


System.out.println("BufferedOutputStream is OK, ready to exit");
Thread.sleep(5*1000);

System.exit(0);




// deleteFolder("/var/lib/log");
}

static void deleteFolder(String path) {
File f = new File(path);
if (f.isDirectory()) {
File[] files = f.listFiles();
for (File file : files) {
if (!file.isDirectory()) {
file.deleteOnExit();
} else {
deleteFolder(file.getAbsolutePath());
boolean b = file.delete();
System.out.println(b+"--"+file.getAbsolutePath());
}
}
}
}
}


package com.sides.file;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

/****************************************************************************
* com.sides.file WriterThread.java Created on 2013-12-3
*
* @Author: linfenliang
* @Description:
* @Version: 1.0
***************************************************************************/
public class WriterThread implements Callable<Boolean> {
private static final Logger logger = Logger.getLogger(WriterThread.class);
private List<Map<String,Object>> dataList;
private String filePath;
private boolean nioWrite;
public WriterThread(List<Map<String,Object>> dataList,String filePath,boolean isNio){
this.dataList = dataList;
this.filePath = filePath;
this.nioWrite = isNio;
}
@Override
public Boolean call() throws Exception {
try {
File folder = new File(this.filePath).getParentFile();
if(!folder.exists()){
folder.mkdir();
}
JSONArray dataArr = JSONArray.fromObject(dataList,DataFactory.jsonConfig);
for(int i=0;i<720;i++){
if(nioWrite){
nioWriteFile(filePath, dataArr);
}else{
commonIoWriteFile(filePath, dataArr);
}
}
} catch (Exception e) {
System.err.println(String.format("data list write error,source data is :%s, filePath is :%s, error message is:%s", dataList,filePath,e));
return false;
}
System.out.println(this.filePath + "finished");
return true;
}
static final void commonIoWriteFile(final String fileName, final Collection data) throws IOException{
FileUtils.writeLines(new File(fileName), "UTF-8", data, IOUtils.LINE_SEPARATOR_UNIX, true);
}
static final void nioWriteFile(final String fileName, final JSONArray arr) throws IOException{
FileOutputStream fops = new FileOutputStream(fileName,true);
FileChannel writeChannel = fops.getChannel();
JSONObject obj = null;
Iterator<JSONObject> iter = arr.iterator();
while(iter.hasNext()){
obj = iter.next();
writeChannel.write(ByteBuffer.wrap(obj.toString().concat(IOUtils.LINE_SEPARATOR_UNIX).getBytes()));
}
writeChannel.close();
fops.close();
}
}



测试结果令我很失望,本来打算做原始数据存储的,结果写文件太耗费性能了,无法接受,值得一提的是NIO写大文件
速度还是蛮快的。

下一步打算数据直接存储到内存中,待测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值