java操作大文件复制

    1.大文件的复制可以用java nio中的channel-to-channel传输,Channel-to-channel传输是可以极其快速的,特别是在底层操作系统提供本地支持的时候。某些操作系统可以不必通过用户空间传递数据而进行直接的数据传输。对于大量的数据传输,这会是一个巨大的帮助。

   2.代码



package com.dingwang.File;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

/**
 * 类FileToFile.java的实现描述:TODO 类实现描述 <br>
 * 将一个文件中的内容写到另一个文件
 * 
 * @author wangding_91@163.com 2016年2月5日 上午11:55:26
 */
public class FileToFile {

    private static final int DEFAULT_BUFFER = 3 * 1024;

    /**
     * 利用通道copy文件
     * 
     * @param source
     * @param target
     */
    public void transfer(File source, File target) {

        FileInputStream in = null;
        FileOutputStream out = null;
        if (!source.exists() || !source.isFile()) {
            throw new IllegalArgumentException("file not exsits!");
        }

        if (target.exists()) {
            target.delete();
        }

        try {
            target.createNewFile();
            in = new FileInputStream(source);
            out = new FileOutputStream(target);
            FileChannel inChannel = in.getChannel();
            WritableByteChannel outChannel = out.getChannel();
            inChannel.transferTo(0, inChannel.size(), outChannel);
            inChannel.close();
            outChannel.close();
            in.close();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 传统的输入输出流copy文件
     * 
     * @param source
     * @param target
     */
    public void transfer2(File source, File target) {
        InputStream in = null;
        OutputStream out = null;
        if (!source.exists() || !source.isFile()) {
            throw new IllegalArgumentException("file not exsits!");
        }

        if (target.exists()) {
            target.delete();
        }

        byte[] buffer = new byte[DEFAULT_BUFFER];
        int n = 0;

        try {
            target.createNewFile();
            in = new BufferedInputStream(new FileInputStream(source));
            out = new BufferedOutputStream(new FileOutputStream(target));
            while ((n = in.read(buffer)) != -1) {
                out.write(buffer, 0, n);
            }
            out.flush();
            in.close();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}



package com.dingwang.file;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.Test;

import com.dingwang.File.FileToFile;

/**
 * 类FileToFileTest.java的实现描述:TODO 类实现描述
 * 
 * @author wangding_91@163.com 2016年2月5日 下午12:05:58
 */
public class FileToFileTest {

    //    @Test
    public void FileToFile() {
        String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String username = System.getProperty("user.name");
        FileToFile f = new FileToFile();
        File source = new File("E:\\生产问题查询\\policy_biz_id_2015.dat");
        String targetFileName = "E:\\生产问题查询\\target_" + username + "_" + date + ".dat";
        File target = new File(targetFileName);
        Long start = System.currentTimeMillis();
        f.transfer(source, target);
        System.out.println("耗时=" + ((System.currentTimeMillis() - start)) + "ms");
    }

    @Test
    public void transfer2() {
        String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String username = System.getProperty("user.name");
        FileToFile f = new FileToFile();
        //E:\\生产问题查询\\policy_biz_id_2015.dat
        File source = new File("E:\\生产问题查询\\policy_biz_id_2015.dat");
        String targetFileName = "E:\\生产问题查询\\target_" + username + "_" + date + ".dat";
        File target = new File(targetFileName);
        Long start = System.currentTimeMillis();
        f.transfer2(source, target);
        System.out.println("耗时=" + ((System.currentTimeMillis() - start)) + "ms");
    }
}


比较了下,利用通道复制文件比传统方式的大概快1倍有余,对于cpu和内存的消耗也更低,测试的时候用的300M的文件;监控用的jvisualvm


程序测试可用,直接解压导入到工程就可以,bat文件跟shell文件是用于在window跟linux上直接执行的脚本 我把开发的配置文档附上: 1.程序为定时任务,任务执行时间在bin目录下的配置文件mergeFilleUtil.properties中配置,在配置文件中,TASK_PERIOD表示任务执行时间间隔,单位为妙,如一天的时间间隔配置是86400,TASK_BEGIN_HOUR表示任务开始的小时时间,比如9点,TASK_BEGIN_MINUTE表任务开始的分钟,比如30分。 2. 程序用log4j记录日志,日志分正常信息跟错误信息两个级别,日志文件存放在log4j文件夹下。考虑到文件很多,日志解压、移动文件每解压、移动1000个记录一次,合并、删除文件每合并、删除50000个记录一次, 3. 启动任务前需配置文件解压合并的路径,本程序需配置的路径如下: 1). PROVINCE_DIR:原始文件存放的路径,必须配置到省的上一级路径,比如存放安徽省的文件路径为E:\test\rootfile\anhui,那么文件的路径必须配置为E:\test\rootfile,否则不能正确显示合并结果; 2). UN_ZIP_PATH:存放解压后的文件的路径; 3). OUT_PATH:存放合并后的文件路径; 4). DONE_FILE_PATH:存放已经解压处理过的文件; 5). DELETE_PATH:配置程序运行结束后欲删除文件的路径,如想删除多个文件夹下的文件,路径之间用逗号隔开,勿加空格,比如:E:\test\rootfile,E:\test\unZip; 4. 注意事项: 本解压合并程序处理文件的逻辑如下: 程序每次解压都去PROVINCE_DIR文件下去解压,将解压后的文件存放到UN_ZIP_PATH下,之后程序启动合并程序合并UN_ZIP_PATH下文件,将合并后的文件按照省份名称存放到OUT_PATH,一个一个文件。当解压合并结束后,程序将PROVINCE_DIR路径下的文件移动到DONE_FILE_PATH下,并且删除PROVINCE_DIR跟UN_ZIP_PATH下文件,这样保证程序每次运行PROVINCE_DIR文件夹下的文件跟UN_ZIP_PATH下的文件都是最新未处理过的,避免了不断判断文件历史记录所带来的大量时间消耗。 所以为了保证文件解压跟合并的正确性,必须配置好DELETE_PATH路径下的文件,否则合并后的结果是不准确的。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值