将非常大量的记录逐行写入文本文件,每行的每个数据项都有固定长度,例如
名称1(60字节)代码1(20字节)xxxxxxx
名称2(60字节)代码2(20字节)xxxxxxx
...
.
.
请问如何提高效率?

解决方案 »

  1.   

    10万行这么少,要什么高效啊
    直接用java的api效率就很高了    try {
            BufferedWriter out = new BufferedWriter(new FileWriter("filename", true));
            out.write("aString");
            out.close();
        } catch (IOException e) {
        }
      

  2.   

    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.
      

  3.   

    写50万行也就是10秒。(我读30万行的数据只要5秒之内吧)其实如果处理这种量的话,建议用内存映射文件写个DLL,然后用JNI调用。也许会好些。
      

  4.   

    healer_kx(甘草(我很看好你哦~~~)):
    犯不着用JNI!
    FileOutputStream本来就是JNI实现的~tinwoo(稻草人) :
    用BufferedOutputStream实现吧,比BufferedWriter稍微快些(10~20%的样子)
      

  5.   

    都错,你们说的太低级了,真想快速写只有用nio,然后利用磁盘的dma技术就能真正快的写!
    用我写的代码要比普通的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 );
        }
      }
    }
      

  6.   

    wmzsl(王明哲):
    我测试过了,很遗憾,在我的笔记本上,nio和io没有性能上的区别~
      

  7.   

    hehe, 我也刚做了测试,好像结论跟 hbwhwang 一样:我分别用 io 和 nio 复制一个 50M 的文件,每运行一次交替复制共三次。
    两次运行的结果分别是:
    ——第一次——
    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));
        }}
      

  8.   

    > 真想快速写只有用nio,然后利用磁盘的dma技术就能真正快的写!这句话我没太看明白,老兄的意思是“nio 由于使用了 dma 技术,所以快”?还是“用 nio,然后再通过自己的程序使用 dma 技术,就可以快”?
      

  9.   

    50万行的数据很小了,不如一次写入内存,然后通过JNI转给内存映射文件。
    这个是我觉得最快的了。关键不知道JNI有多快速。to hbwhwang,
    问题不在JNI上,是内存映射文件。
      

  10.   

    healer_kx(甘草(我很看好你哦~~~)):兄弟,无论你怎么做,也得用IO往磁盘上写啊!
    瓶颈不在内存的操作上,而是IO!
      

  11.   

    哈哈,来一场技术大比武!  ^_^哪位先给搭个擂台?(像 robocode 坦克大战那种的~~)
      

  12.   

    healer_kx(甘草(我很看好你哦~~~)) :
    呵呵,你用C++写个内存映射文件的代码,让我看看它是怎么不用IO来把内存写到硬盘上的~~
      

  13.   

    你误解我的意思了,最后肯定是存在IO操作的,只是整个写的过程中是在写内存。
    而最后把内存中的内容写到硬盘上也是OS在做,非常的快,。
    知道BerkleyDB嘛?它的本质就是写内存,。而且实现就应该是FileMapping
      

  14.   

    用个文本数据库HQLDB什么的不是很方便么?
      

  15.   

    看你的数据源是什么,
    如果是file to file,以上的方法的确会快些
    但是如果是char to file 或者string to file
    用FileWriter就够了。
    区区几十万行而已
      

  16.   

    另外,请好好看看jdoc里面的说明吧
    FileOutputStream is meant for writing streams of raw bytes such as image data. For writing streams of characters, consider using FileWriter. 而BufferedOutputStream也是继承了FileOutputStream !
      

  17.   

    上面那个说nio的,也请好好看看楼主的需求
      

  18.   

    nio  的操作以block为单位
    stream 的操作以byte为单位
    writer 的操作以character为单位
    但是在
    (1)几十万行数据
    (2)输出是从char->file 或者string ->file
    的情况下,根本体会不到nio的优越性,
    stream和writer的效率也不会有什么差异上面的测试程序都是file->file
    你们再写一个string->file的试试楼主不就是要的string->file吗
      

  19.   

    我上面给出的例子应该是java程序本身能最高效率的了!为什么测不出性能差别,因为你测试的东西太小了! 就好像奔腾3(800)和奔腾4(3G)同时跑CS游戏,其他配置都一样!你感觉这两个能有什么差别吗?
    如果真的想测试出差别,你就用大数据量跑,然后计算到毫秒,不要用手笔计算,写一个程序计算,这样你就会知道多快了!关键是这句ByteBuffer buffer = ByteBuffer.allocateDirect( 1024 ); 分配一个直接缓存,这个直接会用到dma的技术!你们可以去google查一下,ibm的nio培训教程,这个例子的来源就是ibm!ibm说这样是最快的办法!
      

  20.   

    以下是我又做的 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
      

  21.   

    感谢 wmzsl(王明哲) 老兄的指导,我去学习了一下 IBM 的那个 NIO 教程,受益匪浅。不过,就本帖涉及到的问题,我还是跟老兄有点不同意见。首先,我只看到教程里说 NIO 是“块操作”,并没有提到 DMA。我理解,无论 IO 还是 NIO,都是在说“在内存中的操作方法”,真正写到硬盘上去的时候,是由操作系统底层控制的,恐怕想不是 DMA 都不行吧?再有,教程中有这样一段话:【在 JDK 1.4 中原来的 I/O 包和 NIO 已经很好地集成了。 java.io.* 已经以 NIO 为基础重新实现了,所以现在它可以利用 NIO 的一些特性。例如, java.io.* 包中的一些类包含以块的形式读写数据的方法,这使得即使在更面向流的系统中,处理速度也会更快。】这也许能解释我前面几次的实验结果。至于用 10G 以上数据做实验,我就不做了,没那个条件,而且,好像也没有必要了。
      

  22.   

    > 请问NIO的教程哪里有?用 google 查【ibm nio 教程】,第一个结果就是。
      

  23.   

    天,我忍不住来说c的好处...跑,我会被javaer的口水淹死D
      

  24.   

    > 天,我忍不住来说c的好处...
    > 跑,我会被javaer的口水淹死D别跑!回来说说 C 都有什么好处,然后我用 JNI 享受它! haha
      

  25.   

    好吧好吧,
    我以为楼主要的是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) {
        }楼主说:我要切点土豆,麻烦给把好点的菜刀
    你给人家一把青虹剑。
      

  26.   

    文档中关于
    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. 这个方法,可以有效利用操作系统的特征。在不同平台下测试,效率可能有较大差异。
    如果仅是复制文件,这个效率应该算很高的了。
      

  27.   

    王明哲说的nio效率的确会高,尤其是在大数据情况下,
    但是你的例子用了一个循环来操作,
    只是用了一个很烂的例子来说明一个优秀的理论
      

  28.   

    不错,nio 的确是个好东西,只要能恰当地使用它。我正在学习 nio ~~
      

  29.   

    masse(当午) 要是早点出来说话,我也就不会把那个复制文件的例子跑来跑去的了,硬盘都快成车床了,而且,我真的差点去弄个 10G 的文件来跑 :((
      

  30.   

    回过头来说,对于 string -> file 这种应用,甘草兄的“文件映射”的确是效率更好的,只不过不必用 C++ 来做了,nio 中已经有了:MappedByteBuffer
      

  31.   

    maquan('ma:kju) 我改了一下你的程序,测试证明,如果连续执行,前一次copy对后一次多少有些影响。
    所以我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));
        }
      

  32.   

    俺新手,俺想请问一下大家,怎么能做到10万数据一次读到内存里面???有个access文件,里面有5W条数据,俺每次将它们一次读出来的时候,java就报错了,说内存溢出 我将所有数据都放在Vector里面,ArrayList也试过,一样报错。怎么能解决这个问题呢??
      

  33.   

    最好别这么干。
    access也可以用游标的吧。
      

  34.   

    啥DMA啊,不太相信NIO能用到DMA的东东。难不成他直接deviceiocontrol
      

  35.   

    呵呵努力学习 oracle ebs 中CSDN论坛浏览器:http://CoolSlob.ys168.com/
      

  36.   

    to masse(当午) 兄:
    锄禾在哪??~~
      

  37.   

    复人:maquan('ma:kju) ( 五级(中级)) 信誉:100  2006-8-16 12:10:56  得分:0
    ?  > 天,我忍不住来说c的好处...
    > 跑,我会被javaer的口水淹死D别跑!回来说说 C 都有什么好处,然后我用 JNI 享受它! haha用标准库的效率就很高了:
    fopen...
    ...
    char buf[10240];
    while(fgets(buf, sizeof(buf), fpi)){
         fprintf(fpo, "%s", buf);
    }fclose...