import java.io.*;
import java.util.*;
import org.apache.commons.io.*;
public class ExternSort {
/**
* @param args
*/
private String inFilePath;
private String outFilePath;
private int memCount;
public ExternSort(String inFilePath, String outFilePath, int memCount) {
super();
this.inFilePath = inFilePath;
this.outFilePath = outFilePath;
this.memCount = memCount;
}
// 创建分割生成的小文件
public void createSmallFile(ArrayList<String> list, int listNum)
throws IOException {
String listOutPath = outFilePath
.replace(".txt", "_" + listNum + ".txt");
// 对List里的值进行排序
Collections.sort(list);
File smallFile = new File(listOutPath);
BufferedWriter bw = new BufferedWriter(new FileWriter(smallFile));
// 将List里的值放入文件
if (list != null && !list.isEmpty()) {
for (String listInfo : list) {
bw.write(listInfo);
bw.newLine();
}
}
list.clear(); // 清空List,以便于存储小一组数据
bw.close();
}
// 将有序的小文件合并
public void mergeFile(int listNum) throws Exception {
File outFile = new File(outFilePath);
BufferedWriter bw = new BufferedWriter(new FileWriter(outFile));
for (int i = 0; i <= listNum; i++) {
String listInPath = outFilePath.replace(".txt", "_" + i + ".txt");
File smallFile = new File(listInPath);
BufferedReader br = new BufferedReader(new FileReader(smallFile));
String aLine = null;
while ((aLine = br.readLine()) != null) { // 如果下一行不为空,则循环继续
bw.write(aLine);
bw.newLine();
}
System.out.println(i);
br.close();
smallFile.delete();
}
bw.close();
System.out.println("File Merge successfully!");
}
// 检查生成的大文件是否正确
public int checkOutputFile(String inFilePath, String outFilePath,
int memCount) throws Exception {
File inFile = new File(inFilePath);
File outFile = new File(outFilePath);
BufferedReader inbr = new BufferedReader(new FileReader(inFile));
BufferedReader outbr = new BufferedReader(new FileReader(outFile));
int result = 0, num = 0;
String inAline = null, outAline = null;
int in = 0, out = 0;
int inOne[] = new int[memCount + 1], outOne[] = new int[memCount + 1];
int inTen[] = new int[memCount + 1], outTen[] = new int[memCount + 1];
int inOneSum = 0, outOneSum = 0;
int inTenSum = 0, outTenSum = 0;
while (((inAline = inbr.readLine()) != null)
&& ((outAline = outbr.readLine()) != null)) {
num++;
in = Integer.parseInt(inAline.replaceAll("\\D", ""));
out = Integer.parseInt(outAline.replaceAll("\\D", ""));
inOne[num] = in % 10;
outOne[num] = out % 10;
if (in >= 100) {
inTen[num] = (in - (in / 100) * 100) / 10;
} else {
inTen[num] = in / 10;
}
if (out >= 100) {
outTen[num] = (out - (out / 100) * 100) / 10;
} else {
outTen[num] = out / 10;
}
inOneSum += inOne[num];
outOneSum += outOne[num];
inTenSum += inTen[num];
outTenSum += outTen[num];
if (num == memCount) {
if ((inOneSum == outOneSum) && (inTenSum == outTenSum)) {
result += 0;
} else {
result += 1;
}
System.out.println("inOneSum:" + inOneSum + "\t" + "outOneSum:"
+ outOneSum);
System.out.println("inTenSum:" + inTenSum + "\t" + "outTenSum:"
+ outTenSum);
inOneSum = 0;
outOneSum = 0;
inTenSum = 0;
outTenSum = 0;
num = 0;
}
}
if ((inOneSum == outOneSum) && (inTenSum == outTenSum)) {
result += 0;
} else {
result += 1;
}
if (((inAline = inbr.readLine()) != null)
|| ((outAline = outbr.readLine()) != null)) {
result += 1;
}
System.out.println("inOneSum:" + inOneSum + "\t" + "outOneSum:"
+ outOneSum);
System.out.println("inTenSum:" + inTenSum + "\t" + "outTenSum:"
+ outTenSum);
System.out.println(result);
if (result == 0)
System.out.println("OutputFile is Right!");
else
System.out.println("OutputFile is Wrong!");
inbr.close();
outbr.close();
return result;
}
// 对文件内容进行排序
public int checkFile(String inFilePath, String outFilePath, int memCount)
throws Exception {
File outFile = new File(outFilePath);
BufferedReader outbr = new BufferedReader(new FileReader(outFile));
File inFile = new File(inFilePath);
BufferedReader inbr = new BufferedReader(new FileReader(inFile));
String outALine = null;
String inALine = null;
// ArrayList<String> outFileList = new ArrayList();
// ArrayList<String> inFileList = new ArrayList();
int in[] = new int[memCount];
int inOne[] = new int[memCount];
int inTen[] = new int[memCount];
int out[] = new int[memCount];
int inOneSum = 0;
int inTenSum = 0;
int outOne[] = new int[memCount];
int outTen[] = new int[memCount];
int outOneSum = 0;
int outTenSum = 0;
int i = 0;
int result = 0;
while (((outALine = outbr.readLine()) != null)
&& ((inALine = inbr.readLine()) != null)) {
out[i] = Integer.parseInt(outALine.replaceAll("\\D", ""));
outOne[i] = out[i] % 10;
if (out[i] >= 100) {
outTen[i] = (out[i] % 100) / 10;
} else {
outTen[i] = out[i] / 10;
}
in[i] = Integer.parseInt(inALine.replaceAll("\\D", ""));
inOne[i] = out[i] % 10;
if (out[i] >= 100) {
inTen[i] = (out[i] % 100) / 10;
} else {
inTen[i] = out[i] / 10;
}
// outFileList.add(outALine);
// inFileList.add(inALine);
outOneSum += outOne[i];
outTenSum += outTen[i];
inOneSum += inOne[i];
inTenSum += inTen[i];
if (i == (memCount - 1)) {
System.out.println("outOneSum :" + outOneSum + "outTenSum : "
+ outTenSum);
System.out.println("inOneSum :" + inOneSum + "inTenSum :"
+ inTenSum);
if ((outOneSum == inOneSum) && (outTenSum == outTenSum)) {
result += 0;
} else {
result += 1;
}
i = 0;
outOneSum = 0;
outTenSum = 0;
inOneSum = 0;
inTenSum = 0;
}
i++;
}
System.out.println("outOneSum :" + outOneSum + "outTenSum : "
+ outTenSum);
System.out.println("inOneSum :" + inOneSum + "inTenSum :" + inTenSum);
if ((outOneSum == inOneSum) && (outTenSum == outTenSum)) {
result += 0;
} else {
result += 1;
}
if (((outALine = outbr.readLine()) != null)
|| ((inALine = inbr.readLine()) != null)) {
result += 1;
} else {
result += 0;
}
if (result == 0)
System.out.println("OutputFile is Right!");
else
System.out.println("OutputFile is Wrong!");
inbr.close();
outbr.close();
return result;
}
// 分割大文件
public int splitFile() throws Exception {
File file = new File(inFilePath);
ArrayList<String> list = new ArrayList<String>();
String aLine = null;
int listNum = 0;
BufferedReader br = new BufferedReader(new FileReader(file));
while ((aLine = br.readLine()) != null) { // 如果下一行不为空,则循环继续
list.add(aLine);
if (list.size() >= memCount) {
createSmallFile(list, listNum); // 当行数等于设定的值时,将存在List里的值写入小文件中
System.out.println(listNum);
listNum++;
}
}
createSmallFile(list, listNum); // 将剩下的内容,写入下一个小文件中
System.out.println(listNum);
br.close();
System.out.println("File was splited successfully!");
System.out.println(listNum);
return listNum;
}
public void mergeSortFiles(int listNum) throws Exception {
int j = listNum;
int num = 0;
while (j >= 1) {
num = 0;
for (int i = 0; i <= j; i += 2) {
String leftPath = outFilePath.replace(".txt", "_" + i + ".txt");
File leftFile = new File(leftPath);
String rightPath = outFilePath.replace(".txt", "_" + (i + 1)
+ ".txt");
File rightFile = new File(rightPath);
File targetFile = new File(outFilePath.replace(".txt", "_sort"
+ num + ".txt"));
merge(leftFile, rightFile, targetFile);
leftFile.delete();
rightFile.delete();
renameFile(targetFile,new File(outFilePath.replace(".txt", "_" + num + ".txt")));
if(targetFile.delete())
System.out.println("target File was deleted successfully!");
else
System.out.println("target File was deleted failed");
System.out.println("num is:" + num);
num++;
}
j = num - 1;
}
renameFile(new File(outFilePath.replace(".txt", "_" + 0 + ".txt")),new File(outFilePath));
}
public void merge(File leftFile, File rightFile, File targetFile)
throws Exception {
BufferedReader leftbr = new BufferedReader(new FileReader(leftFile));
BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile));
String leftAline = null, rightAline = null;
leftAline = leftbr.readLine();
if (!rightFile.exists()) {
while (leftAline != null) {
bw.write(leftAline);
bw.newLine();
leftAline = leftbr.readLine();
}
rightFile.delete();
} else {
BufferedReader rightbr = new BufferedReader(new FileReader(
rightFile));
int leftInt = 0, rightInt = 0;
rightAline = rightbr.readLine();
while ((leftAline != null) && (rightAline != null)) {
leftInt = Integer.parseInt(leftAline.replaceAll("\\D", ""));
rightInt = Integer.parseInt(rightAline.replaceAll("\\D", ""));
if (leftInt <= rightInt) {
bw.write(leftAline);
bw.newLine();
leftAline = leftbr.readLine();
} else {
bw.write(rightAline);
bw.newLine();
rightAline = rightbr.readLine();
}
}
if (leftAline != null) {
while (leftAline != null) {
bw.write(leftAline);
bw.newLine();
leftAline = leftbr.readLine();
}
}
if (rightAline != null) {
while (rightAline != null) {
bw.write(rightAline);
bw.newLine();
rightAline = rightbr.readLine();
}
}
rightbr.close();
}
leftbr.close();
}
public void renameFile(File oldFile,File newFile) throws IOException{
FileUtils.copyFile(oldFile, newFile);
oldFile.deleteOnExit();
if(oldFile.delete())
System.out.println("renameFile deleted successfully ");
}
public static void main(String[] args) throws Exception {
String filePath = System.getProperty("user.dir");
String inFilePath = filePath + "\\input.txt";
String outFilePath = filePath + "\\output.txt";
int memCount = 100000;
ExternSort externSort = new ExternSort(inFilePath, outFilePath,
memCount);
int listNum = externSort.splitFile();
externSort.mergeSortFiles(listNum);
//externSort.mergeFile(listNum);
// externSort.checkOutputFile(inFilePath, outFilePath, memCount);
externSort.checkFile(inFilePath, outFilePath, memCount);
}
}