package com.weidou.mota.output;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class FileSuper {
public static final long KB = 1024l;
public static final long MB = 1024 * KB;
public static final long GB = 1024 * MB;
private FileSuper() {
}
public static Set<File> folderWalk(String path) {
File folder = new File(path);
Set<File> fileList = new HashSet<File>();
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
fileList.addAll(folderWalk(file.getAbsolutePath()));
} else {
fileList.add(file);
}
}
return fileList;
}
public static boolean spiltFilesBySize(BlockingQueue<File> fileQueue,
final long dataSize, File outPutDir, final String fileSuffix,
final String filePrex) throws IOException {
if (!(outPutDir.isDirectory() && outPutDir.exists())) {
throw new IllegalArgumentException("不存在路径 或者路径不是文件夹 :"
+ outPutDir.getAbsolutePath());
}
long remainSize = 0;// 要生成的文件还有剩余大小
int outFileSeq = 1; //输出文件序号
long fileInSize = 0; //输入文件大小
long fileInRemainSize = 0; //文件剩下的大小
FileChannel outFile = null; //文件输出nio
FileChannel fileIn = null; //文件输入nio
while (!fileQueue.isEmpty()) { //看是否还有文件
if (fileInRemainSize <= 0) {//如果输入文件已经全部存入
if (fileIn != null) { //判断文件是否为空
fileIn.close(); //关闭输入文件
fileIn = null; //输入文件为null
}
File filePoll = fileQueue.poll(); //取得一个输入文件
fileIn = getInfile(filePoll); //获得读入文件nio
fileInRemainSize = fileIn.size(); // 文件的指针 = fileInSize -
// fileInRemainSize
fileInSize = fileIn.size(); //记录文件大小
}
if (remainSize <= 0) { //距离一个生成的文件还有多少
if (outFile != null) { //输出文件不为空
outFile.close(); //输入文件关闭
}
outFile = getOutFile(outPutDir, fileSuffix, filePrex,
outFileSeq); //生成一个文件输出nio
outFileSeq = outFileSeq + 1; //序列号 + 1
remainSize = dataSize; //重置文件输出大小
}
long cutFileInPoint = 0l; //文件结构 [已经输出大小 + fileInRemainSize ] <=fileInSize
if (fileInRemainSize > remainSize) {
cutFileInPoint = remainSize;
remainSize = 0;
} else if (fileInRemainSize <= remainSize) {
cutFileInPoint = fileInRemainSize;
remainSize = remainSize - cutFileInPoint;
}
//这块是重点 nio 不支持大于4g数据的复制,所以一块块复制(切片复制)
for (long count = 0; count <= cutFileInPoint; count = count
+ 70 * MB) { //这里粗犷的处理 , 因为文件数据很多丢失 《 70 mb 不算什么
fileIn.transferTo(fileInSize - fileInRemainSize + count,
70 * MB, outFile); //复制
}
fileInRemainSize = fileInRemainSize - cutFileInPoint; //
}
return true;
}
@SuppressWarnings("resource")
public static FileChannel getInfile(File file) throws FileNotFoundException {
return new FileInputStream(file).getChannel();
}
@SuppressWarnings("resource")
public static FileChannel getOutFile(File outPutDir,
final String fileSuffix, final String filePrex, int outFileSeq)
throws FileNotFoundException {
return new FileOutputStream(new File(outPutDir.getAbsolutePath() + "/"
+ fileSuffix + outFileSeq + filePrex)).getChannel();
}
public static void main(String args []) throws IOException
{
if (args.length < 4) {
throw new IllegalArgumentException("参数太少");
}
List<String> inputPaths = new ArrayList<String>();
String prex = "NO_";
String suffix = ".csv";
long size = FileSplit.GB * 50;
File output = null;
for (int i = 0; i < args.length; i++) {
String choice = args[i];
if (choice.equals("--filelist")) {
for (String path : args[i + 1].split("#")) {
inputPaths.add(path.trim());
}
i = i + 1;
} else if (choice.equals("--prex")) {
prex = args[i + 1];
i = i + 1;
} else if (choice.equals("--suffix")) {
suffix = args[i + 1];
i = i + 1;
} else if (choice.equals("--output")) {
output = new File(args[i + 1]);
i = i + 1;
} else if (choice.equals("--filegb")) {
}
}
if (StringUtils.isEmpty(prex) || StringUtils.isEmpty(suffix)
|| inputPaths.size() <= 0 || output == null) {
throw new IllegalArgumentException("输入参数有误!");
}
BlockingQueue<File> fileQueue = new LinkedBlockingDeque<File>();
for (String path : inputPaths) {
fileQueue.addAll(folderWalk(path));
}
spiltFilesBySize(fileQueue, size, output, prex, suffix);
}
}
我写这个是在看数据生成,拭了很多把都失败了,刚开始心急如焚,后来继续测试,用了过去读取文件(按行),在写(慢死)
不过最后写出来了 , 里面虽然少了很多对异常的判断 ,但是基本可以满足使用
已经夜里1点了 看来我在等到很晚才睡 ,各位晚安