10万行这么少,要什么高效啊 直接用java的api效率就很高了 try { BufferedWriter out = new BufferedWriter(new FileWriter("filename", true)); out.write("aString"); out.close(); } catch (IOException e) { }
BufferedWriter的说明:Write text to a character-output stream, buffering characters so as to provide for the efficient writing of single characters, arrays, and strings. The buffer size may be specified, or the default size may be accepted. The default is large enough for most purposes. A newLine() method is provided, which uses the platform's own notion of line separator as defined by the system property line.separator. Not all platforms use the newline character ('\n') to terminate lines. Calling this method to terminate each output line is therefore preferred to writing a newline character directly.
看你的数据源是什么, 如果是file to file,以上的方法的确会快些 但是如果是char to file 或者string to file 用FileWriter就够了。 区区几十万行而已
另外,请好好看看jdoc里面的说明吧 FileOutputStream is meant for writing streams of raw bytes such as image data. For writing streams of characters, consider using FileWriter. 而BufferedOutputStream也是继承了FileOutputStream !
以下是我又做的 4 次实验,其中调整了文件大小和程序运行时开辟的缓冲区大小。如果这就是所谓“IBM 的 DMA 技术”的效果的话,那恐怕得算是“屠龙技”了。(也许是只有 IBM 提供的 JVM 才是那个样子吧~~)// 复制文件大小: 50M 缓冲区: 1024*512 io time cost: 9764 nio time cost: 10996 io time cost: 9654 nio time cost: 9564 io time cost: 9183 nio time cost: 5748// 复制文件大小: 50M 缓冲区: 1024*512 io time cost: 11527 nio time cost: 11716 io time cost: 10145 nio time cost: 10285 io time cost: 12267 nio time cost: 10395// 复制文件大小: 100M 缓冲区: 1024*512 io time cost: 20380 nio time cost: 19207 io time cost: 20410 nio time cost: 20008 io time cost: 21571 nio time cost: 24396// 复制文件大小: 100M 缓冲区: 1024*512 io time cost: 24665 nio time cost: 24546 io time cost: 22682 nio time cost: 22903 io time cost: 23734 nio time cost: 23704
文档中关于 FileChannel.transferFrom方法的说明This method is potentially much more efficient than a simple loop that reads from the source channel and writes to this channel. Many operating systems can transfer bytes directly from the source channel into the filesystem cache without actually copying them. 这个方法,可以有效利用操作系统的特征。在不同平台下测试,效率可能有较大差异。 如果仅是复制文件,这个效率应该算很高的了。
直接用java的api效率就很高了 try {
BufferedWriter out = new BufferedWriter(new FileWriter("filename", true));
out.write("aString");
out.close();
} catch (IOException e) {
}
犯不着用JNI!
FileOutputStream本来就是JNI实现的~tinwoo(稻草人) :
用BufferedOutputStream实现吧,比BufferedWriter稍微快些(10~20%的样子)
用我写的代码要比普通的io快的多,你去自己再研究研究java的nio包下的东西吧!我就说这么多import java.io.*;
import java.nio.*;
import java.nio.channels.*;public class FastCopyFile
{
static public void main( String args[] ) throws Exception {
if (args.length<2) {
System.err.println( "Usage: java FastCopyFile infile outfile" );
System.exit( 1 );
} String infile = args[0];
String outfile = args[1]; FileInputStream fin = new FileInputStream( infile );
FileOutputStream fout = new FileOutputStream( outfile ); FileChannel fcin = fin.getChannel();
FileChannel fcout = fout.getChannel(); ByteBuffer buffer = ByteBuffer.allocateDirect( 1024 ); while (true) {
buffer.clear(); int r = fcin.read( buffer ); if (r==-1) {
break;
} buffer.flip(); fcout.write( buffer );
}
}
}
我测试过了,很遗憾,在我的笔记本上,nio和io没有性能上的区别~
两次运行的结果分别是:
——第一次——
io time cost: 11427
nio time cost: 14240
io time cost: 13480
nio time cost: 9894
io time cost: 10816
nio time cost: 11576
——第二次——
io time cost: 10185
nio time cost: 14160
io time cost: 11697
nio time cost: 11056
io time cost: 9634
nio time cost: 10265源程序如下,能否请 wmzsl(王明哲) 老兄帮看看我做的有什么地方不对吗?package test;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;public class WriteEfficiently { public static void main(String[] args) throws Exception{
String infile = "J:\\TEMP\\SRC.XXX";
String outfile = "J:\\TEMP\\DEST.XXX"; CopyIo(infile, outfile + ".1");
CopyNio(infile, outfile + ".2");
CopyIo(infile, outfile + ".3");
CopyNio(infile, outfile + ".4");
CopyIo(infile, outfile + ".5");
CopyNio(infile, outfile + ".6"); } private static void CopyIo(String infile, String outfile) throws FileNotFoundException, IOException {
long t1 = System.currentTimeMillis(); FileInputStream fin = new FileInputStream(infile);
FileOutputStream fout = new FileOutputStream(outfile); byte[] ba = new byte[1024]; while (true) {
int r = fin.read(ba); if (r == -1) {
break;
} fout.write(ba, 0, r);
}
fout.close();
fin.close(); long t2 = System.currentTimeMillis();
System.out.println("io time cost: " + (t2-t1));
} private static void CopyNio(String infile, String outfile) throws FileNotFoundException, IOException {
long t1 = System.currentTimeMillis(); FileInputStream fin = new FileInputStream(infile);
FileOutputStream fout = new FileOutputStream(outfile); FileChannel fcin = fin.getChannel();
FileChannel fcout = fout.getChannel(); ByteBuffer buffer = ByteBuffer.allocateDirect(1024); while (true) {
buffer.clear(); int r = fcin.read(buffer); if (r == -1) {
break;
} buffer.flip(); fcout.write(buffer);
}
fcout.close();
fcin.close(); long t2 = System.currentTimeMillis();
System.out.println("nio time cost: " + (t2-t1));
}}
这个是我觉得最快的了。关键不知道JNI有多快速。to hbwhwang,
问题不在JNI上,是内存映射文件。
瓶颈不在内存的操作上,而是IO!
呵呵,你用C++写个内存映射文件的代码,让我看看它是怎么不用IO来把内存写到硬盘上的~~
而最后把内存中的内容写到硬盘上也是OS在做,非常的快,。
知道BerkleyDB嘛?它的本质就是写内存,。而且实现就应该是FileMapping
如果是file to file,以上的方法的确会快些
但是如果是char to file 或者string to file
用FileWriter就够了。
区区几十万行而已
FileOutputStream is meant for writing streams of raw bytes such as image data. For writing streams of characters, consider using FileWriter. 而BufferedOutputStream也是继承了FileOutputStream !
stream 的操作以byte为单位
writer 的操作以character为单位
但是在
(1)几十万行数据
(2)输出是从char->file 或者string ->file
的情况下,根本体会不到nio的优越性,
stream和writer的效率也不会有什么差异上面的测试程序都是file->file
你们再写一个string->file的试试楼主不就是要的string->file吗
如果真的想测试出差别,你就用大数据量跑,然后计算到毫秒,不要用手笔计算,写一个程序计算,这样你就会知道多快了!关键是这句ByteBuffer buffer = ByteBuffer.allocateDirect( 1024 ); 分配一个直接缓存,这个直接会用到dma的技术!你们可以去google查一下,ibm的nio培训教程,这个例子的来源就是ibm!ibm说这样是最快的办法!
io time cost: 9764
nio time cost: 10996
io time cost: 9654
nio time cost: 9564
io time cost: 9183
nio time cost: 5748// 复制文件大小: 50M 缓冲区: 1024*512
io time cost: 11527
nio time cost: 11716
io time cost: 10145
nio time cost: 10285
io time cost: 12267
nio time cost: 10395// 复制文件大小: 100M 缓冲区: 1024*512
io time cost: 20380
nio time cost: 19207
io time cost: 20410
nio time cost: 20008
io time cost: 21571
nio time cost: 24396// 复制文件大小: 100M 缓冲区: 1024*512
io time cost: 24665
nio time cost: 24546
io time cost: 22682
nio time cost: 22903
io time cost: 23734
nio time cost: 23704
> 跑,我会被javaer的口水淹死D别跑!回来说说 C 都有什么好处,然后我用 JNI 享受它! haha
我以为楼主要的是string->file的,所以给了上面的代码,而且由于数据量小,所以说了。非要用nio,有给了一个不伦不类的例子(复制文件)。
上面给的测试都是复制,我实在无语。
要复制一个文件,为什么不用下面的代码? try {
FileChannel srcChannel = new FileInputStream("srcFilename").getChannel();
FileChannel dstChannel = new FileOutputStream("dstFilename").getChannel();
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
srcChannel.close();
dstChannel.close();
} catch (IOException e) {
}楼主说:我要切点土豆,麻烦给把好点的菜刀
你给人家一把青虹剑。
FileChannel.transferFrom方法的说明This method is potentially much more efficient than a simple loop that reads from the source channel and writes to this channel. Many operating systems can transfer bytes directly from the source channel into the filesystem cache without actually copying them. 这个方法,可以有效利用操作系统的特征。在不同平台下测试,效率可能有较大差异。
如果仅是复制文件,这个效率应该算很高的了。
但是你的例子用了一个循环来操作,
只是用了一个很烂的例子来说明一个优秀的理论
所以我sleep了5秒。
测试文件是539M。
在我的winxp pro上,nio和io没有什么区别。
直接用transfer的,效率要好些。
我机器:p4 2.4 + 512M你可以再试试。或者换平台试试。 public static void main(String[] args) throws Exception{
String infile = "D:\\game\\swd5\\kog-Swd5a.iso";
String outfile = "D:\\game\\swd5\\kog-Swd5a.iso1";
int i=1;
while(i++<3)
{
Thread.sleep(5000);
copy(infile,outfile);
delete(outfile);
Thread.sleep(5000);
CopyIo(infile, outfile);
delete(outfile);
Thread.sleep(5000);
CopyNio(infile, outfile);
delete(outfile);
} }
private static void delete(String str)throws Exception
{
if(!new File(str).delete())
{
throw new Exception("删除失败");
}
}
private static void copy(String infile,String outfile)throws Exception
{
long t1 = System.currentTimeMillis();
FileChannel srcChannel = new FileInputStream(infile).getChannel();
FileChannel dstChannel = new FileOutputStream(outfile).getChannel();
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
srcChannel.close();
dstChannel.close();
long t2 = System.currentTimeMillis();
System.out.println("copy time cost: " + (t2-t1));
}
access也可以用游标的吧。
锄禾在哪??~~
? > 天,我忍不住来说c的好处...
> 跑,我会被javaer的口水淹死D别跑!回来说说 C 都有什么好处,然后我用 JNI 享受它! haha用标准库的效率就很高了:
fopen...
...
char buf[10240];
while(fgets(buf, sizeof(buf), fpi)){
fprintf(fpo, "%s", buf);
}fclose...