java分割一个千万级数量的文件为多个子文件

1、业务描述:把一个千万条数的文件(fileName.csv)分割为多个子文件的处理;
2、代码实现:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

public class SplitMethod {
//测试类
    public static void main(String[] args) throws Exception {
        String path = "D:\\ydWorkSpace\\testFile\\fileName_201807090.csv";
        splitBigFile(path, "GBK", ",");
    }

    /**
     * 按数据条数分割文件,
     * @param path
     * @param ENCODE
     * @param splitStr
     * @return
     * @throws Exception
     */
    public static void splitBigFile(String path, String ENCODE, String splitStr) throws Exception {
        List<List<String>> outArr = new ArrayList<>();
        File filePath = new File(path);
        String destName = filePath.getName().replace(".csv", "");// 重写文件名
        String destpath = filePath.getParent();// 重写文件路径
        int splitLen = 10000;// 分割子文件的条数,一个文件10w条
        int i = 0;
        // 数据文件不为空
        if (filePath.exists() && filePath.length() > 0) {
            InputStreamReader ips = new InputStreamReader(new FileInputStream(filePath), ENCODE);
            BufferedReader br = new BufferedReader(ips);
            for (String dataLine = null; (dataLine = br.readLine()) != null;) {
                if (dataLine.length() != 0) {
                    String[] arr = dataLine.split(splitStr, -1);
                    List<String> out = new ArrayList<>();
                    for (String str : arr) {
                        out.add(str.replace("^", "")); // 清除特殊字符
                    }
                    outArr.add(out);
                    if (outArr.size() == splitLen) {
                        StringBuffer strbuf = replaceContents(outArr);
                        String newName =
                                new File(destpath + File.separator + destName + "_" + i + ".csv")
                                        .getAbsolutePath();
                        reWriteFile(newName, strbuf.toString(), ENCODE);// 重写文件
                        outArr.clear();// 重写完清空文件
                        i++;
                    }
                }
            }
            br.close();
            ips.close();
        }
        // 分割后最后一个文件
        if (outArr.size() > 0) {
            StringBuffer strbuf = replaceContents(outArr);
            String newName =
                    new File(destpath + File.separator + destName + "_" + i + ".csv")
                            .getAbsolutePath();
            reWriteFile(newName, strbuf.toString(), ENCODE);
        }

    }

    private static StringBuffer replaceContents(List<List<String>> outArr) {
        StringBuffer strbuf = new StringBuffer();
        for (int j = 0; j < outArr.size(); j++) {
            List<String> strs = outArr.get(j);
            for (String txt : strs) {
                // 如果是属于这类数据 无效 置空 华为新数据会有这种情况
                if ("--".equals(txt)) {
                    txt = "";
                }
                strbuf.append(txt + ",");//注意:行分割字符
            }
            strbuf.delete(strbuf.length() - 1, strbuf.length());
            strbuf.append("\n");
        }
        return strbuf;
    }


    /**
     * 重新写入文件
     * @param fileName
     * @param content
     * @param ENCODE
     */
    public static void reWriteFile(String fileName, String content, String ENCODE) {
        try {
            File ff = new File(fileName);
            if (!ff.exists()) {
                ff.createNewFile();
            }
            // 打开一个随机访问文件流,按读写方式
            RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
            // 文件长度,字节数
            long fileLength = randomFile.length();
            // 将写文件指针移到文件尾。
            randomFile.seek(fileLength);
            String toCn = null;
            // 处理中文问题
            toCn = new String(content.getBytes(ENCODE), "ISO-8859-1");
            randomFile.writeBytes(toCn);
            randomFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值