Java 文件操作的几种方式

来源:互联网 发布:2016网络热门词汇 编辑:程序博客网 时间:2024/05/18 11:25

以下程序是采用多种方式对3个文件进行复制

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Date;

import javax.imageio.stream.FileCacheImageInputStream;
import javax.imageio.stream.FileCacheImageOutputStream;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;

public class FileOperate {

    public static void main(String[] args) {
        // 第一个文件大小10M左右、第二个文件大小100M左右,第三个文件大小为1000M左右
        String[] srcname = new String[] { "F:/文件1", "F:/文件2", "F:/文件3" };
        String[] dstname = new String[] { "F:/temp/文件1", "F:/temp/文件2",
            "F:/temp/文件3" };
        int fsize = 1;
        for (int i = 0; i < srcname.length; i++) {
            File fsrc = new File(srcname[i]);
            if (!fsrc.exists()) {
                return;
            }
            File fdst = new File(dstname[i]);
            if (!fdst.exists()) {
                try {
                    fdst.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    return;
                }
            }
            if (0 < i) {
                fsize *= 10;
            }
            System.out.println("***********几种复制" + fsize + " M大小文件方式耗时比较*****************");
            try {
                System.out.print("传统方式流访问耗时: ");
                System.out.println(forStream(fsrc, fdst) + " ms");
                fdst.delete();
                fdst.createNewFile();
                System.out.print("传统方式随机访问耗时: ");
                System.out.println(forRandomAccessFile(fsrc, fdst) + " ms");
                fdst.delete();
                fdst.createNewFile();
                System.out.print("使用影像流读写耗时:");
                System.out.println(forImageStream(fsrc, fdst) + " ms");
                fdst.delete();
                fdst.createNewFile();
                System.out.print("使用内存影像流读写耗时:");
                System.out.println(forCacheImageStream(fsrc, fdst) + " ms");
                fdst.delete();
                fdst.createNewFile();
                System.out.print("使用内存缓存影像流读写耗时:");
                System.out.println(forMemCacheImageStream(fsrc, fdst) + " ms");
                fdst.delete();
                fdst.createNewFile();
                System.out.print("使用NIO中的管道到管道传输耗时: ");
                System.out.println(forTransfer(fsrc, fdst) + " ms");
                fdst.delete();
                fdst.createNewFile();
                System.out.print("使用NIO管道读写耗时:");
                System.out.println(forChannel(fsrc, fdst) + " ms");
                fdst.delete();
                fdst.createNewFile();
                System.out.print("使用NIO管道映射读写耗时:");
                System.out.println(forChannelMap(fsrc, fdst) + " ms");
                fdst.delete();
                // fdst.createNewFile();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static File delAndNewFile(File file) {
        file.deleteOnExit();
        File fdst = new File(file.getAbsolutePath());
        if (!fdst.exists()) {
            try {
                fdst.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            }
        }
        return fdst;
    }

    // 传统的方式,使用io.FileInputStream、FileOutputStream进行文件读写
    public static long forStream(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        FileInputStream in = new FileInputStream(f1);
        FileOutputStream out = new FileOutputStream(f2);
        int length = 2 * 1024 * 1024; // 此处分配空间的大小影响读取数据的速度
        byte[] buffer = new byte[length];
        int readlen = in.read(buffer);
        while (-1 != readlen) {
            out.write(buffer, 0, readlen);
            readlen = in.read(buffer);
        }
        in.close();
        out.flush();
        out.close();
        return new Date().getTime() - time;
    }

    // 传统方式,使用io.RandomAccessFile进行文件读写
    public static long forRandomAccessFile(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        RandomAccessFile in = new RandomAccessFile(f1, "r");
        RandomAccessFile out = new RandomAccessFile(f2, "rw");
        int length = 2 * 1024 * 1024; // 此处分配空间的大小影响读取数据的速度
        byte[] buffer = new byte[length];
        int readlen = in.read(buffer);
        while (-1 != readlen) {
            out.write(buffer, 0, readlen);
            readlen = in.read(buffer);
        }
        in.close();
        out.close();
        return new Date().getTime() - time;
    }

    // 使用NIO中的管道到管道传输,使用FileChannel,并使用FileChannnel.transferTo进行文件传输
    public static long forTransfer(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        FileInputStream in = new FileInputStream(f1);
        FileOutputStream out = new FileOutputStream(f2);
        FileChannel inC = in.getChannel();
        FileChannel outC = out.getChannel();
        inC.transferTo(inC.position(), inC.size(), outC);
        outC.force(false);
        inC.close();
        outC.close();
        in.close();
        out.close();
        return new Date().getTime() - time;
    }

    // 使用NIO中的管道读写操作,使用FileChannel,并使用FileChannnel.read和write进行文件读写
    public static long forChannel(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        FileInputStream in = new FileInputStream(f1);
        FileOutputStream out = new FileOutputStream(f2);
        FileChannel inC = in.getChannel();
        FileChannel outC = out.getChannel();
        ByteBuffer buf = ByteBuffer.allocate(2 * 1024 * 1024); // 此处分配空间的大小影响读取数据的速度
        int readlen = inC.read(buf);
        while ((0 != readlen) && (-1 != readlen)) {
            buf.flip();
            outC.write(buf);
            outC.force(false);
            buf.clear();
            readlen = inC.read(buf);
        }
        inC.close();
        outC.close();
        in.close();
        out.close();
        return new Date().getTime() - time;
    }

    // 使用NIO中管道Map进行读写操作
    public static long forChannelMap(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        FileInputStream in = new FileInputStream(f1);
        RandomAccessFile out = new RandomAccessFile(f2, "rw");
        FileChannel inC = in.getChannel();
        FileChannel outC = out.getChannel();
        long fsize = inC.size();
        MappedByteBuffer inm = inC.map(MapMode.READ_ONLY, 0, fsize);
        int length = 2 * 1024 * 1024; // 此处分配空间的大小影响读取数据的速度
        if (fsize < length) {
            length = (int) fsize;
        }
        MappedByteBuffer readb = inm.load();
        int offset = 0;
        byte[] buffer = new byte[length];
        MappedByteBuffer outm = null;
        while (readb.hasRemaining()) {
            int remain = readb.remaining();
            if (remain < length) {
                length = remain;
            }
            outm = outC.map(MapMode.READ_WRITE, offset, length);
            readb.get(buffer, 0, length);
            outm.put(buffer, 0, length);
            outm.force();
            outm.clear();
            offset += length;
        }
        readb.clear();
        inm.clear();
        //使用MappedByteBuffer进行文件内存映射时,关闭文件channel时无法关闭映射关系,从而导致无法删除文件直到进程退出。
        clean(readb);
        clean(inm);
        clean(outm);

        inC.close();
        outC.close();
        in.close();
        out.close();
        return new Date().getTime() - time;
    }

    // 使用文件FileImageInputStream、FileImageOutputStream
    public static long forImageStream(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        FileImageInputStream inm = new FileImageInputStream(f1);
        FileImageOutputStream outm = new FileImageOutputStream(f2);
        int length = 2 * 1024 * 1024; // 此处分配空间的大小影响读取数据的速度
        byte[] buffer = new byte[length];
        int readlen = inm.read(buffer);
        while (-1 != readlen) {
            outm.write(buffer, 0, readlen);
            readlen = inm.read(buffer);
        }
        inm.close();
        outm.flush();
        outm.close();

        return new Date().getTime() - time;
    }

    // 使用文件FileCacheImageInputStream、FileCacheImageOutputStream
    public static long forCacheImageStream(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        File ftmp = new File("F:/temp/");
        FileInputStream fim = new FileInputStream(f1);
        FileCacheImageInputStream inm = new FileCacheImageInputStream(fim, ftmp);
        FileOutputStream fom = new FileOutputStream(f2);
        FileCacheImageOutputStream outm = new FileCacheImageOutputStream(fom, ftmp);
        int length = 2 * 1024 * 1024; // 此处分配空间的大小影响读取数据的速度
        byte[] buffer = new byte[length];
        int readlen = inm.read(buffer);
        while (-1 != readlen) {
            outm.write(buffer, 0, readlen);
            readlen = inm.read(buffer);
        }
        inm.close();
        outm.flush();
        outm.close();
        fim.close();
        fom.close();
        return new Date().getTime() - time;
    }

    // 使用MemoryCacheImageInputStream、MemoryCacheImageOutputStream
    public static long forMemCacheImageStream(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        FileInputStream fim = new FileInputStream(f1);
        MemoryCacheImageInputStream inm = new MemoryCacheImageInputStream(fim);
        FileOutputStream fom = new FileOutputStream(f2);
        MemoryCacheImageOutputStream outm = new MemoryCacheImageOutputStream(fom);
        int length = 2 * 1024 * 1024; // 此处分配空间的大小影响读取数据的速度
        byte[] buffer = new byte[length];
        inm.reset();
        int readlen = inm.read(buffer);
        while (-1 != readlen) {
            outm.flush();
            outm.write(buffer, 0, readlen);
            inm.flush();
            readlen = inm.read(buffer);
        }
        inm.close();
        fim.close();
        outm.flush();
        outm.close();
        fom.close();

        return new Date().getTime() - time;
    }

    // 传统的方式,使用io.FileReader、FileWriter进行文件读写,注意该方法只能读取字符文件
    public static long forReaderAndWriter(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        FileReader fread = new FileReader(f1);
        FileWriter fwrite = new FileWriter(f2);
        int length = 2 * 1024 * 1024; // 此处分配空间的大小影响读取数据的速度
        char[] buffer = new char[length];
        int readlen = fread.read(buffer);
        while (-1 != readlen) {
            fwrite.write(buffer);
            readlen = fread.read(buffer);
        }
        fread.close();
        fwrite.flush();
        fwrite.close();

        return new Date().getTime() - time;
    }

    /**
     * 清理MappedByteBuffer句柄
     * @param buffer
     */
    public static void clean(final MappedByteBuffer buffer) {
        if (buffer == null) {
            return;
        }
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            public Object run() {
                try {
                    Method getCleanerMethod = buffer.getClass().getMethod("cleaner", new Class[0]);
                    if (getCleanerMethod != null) {
                        getCleanerMethod.setAccessible(true);
                        Object cleaner = getCleanerMethod.invoke(buffer, new Object[0]);
                        Method cleanMethod = cleaner.getClass().getMethod("clean", new Class[0]);
                        if (cleanMethod != null) {
                            cleanMethod.invoke(cleaner, new Object[0]);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
    }
}