是否有比我目前使用的更有效的方法,将文件2的行追加到文件1的行接一行地合并两个文件?
如果file1包含
a2
b2
c2
并且file2包含
a1,a2
b1,b2
c1,c2
然后输出文件应包含
private FileSheet combineRecords(ArrayList<FileSheet> toCombine) throws IOException
{
ArrayList<String> filepaths = new ArrayList<String>();
for (FileSheet sheetIterator : toCombine)
{
filepaths.add(sheetIterator.filepath);
}
String filepathAddition = "";
for (String s : filepaths)
{
filepathAddition = filepathAddition + s.split(".select.")[1].replace(".csv", "") + ".";
}
String outputFilepath = subsheetDirectory + fileHandle.getName().split(".csv")[0] + ".select." + filepathAddition + "csv";
Log.log("Output filepath " + outputFilepath);
long mainFileLength = toCombine.get(0).recordCount();
for (FileSheet f : toCombine)
{
int ordinal = toCombine.indexOf(f);
if (toCombine.get(ordinal).recordCount() != mainFileLength)
{
Log.log("Error : Record counts for 0 + " + ordinal);
return null;
}
}
FileSheet finalValues;
Log.log("Starting iteration streams");
BufferedWriter out = new BufferedWriter(new FileWriter(outputFilepath, false));
List<BufferedReader> streams = new ArrayList<>();
for (FileSheet j : toCombine)
{
streams.add(new BufferedReader(new FileReader(j.filepath)));
}
String finalWrite = "";
for (int i = 0; i < toCombine.get(0).recordCount(); i++)
{
for (FileSheet j : toCombine)
{
int ordinal = toCombine.indexOf(j);
finalWrite = finalWrite + streams.get(ordinal).readLine();
if (toCombine.indexOf(j) != toCombine.size() - 1)
{
finalWrite = finalWrite + ",";
}
else
{
finalWrite = finalWrite + "\n";
}
}
if (i % 1000 == 0 || i == toCombine.get(0).recordCount() - 1)
{
// out.write(finalWrite + "\n");
Files.write(Paths.get(outputFilepath),(finalWrite).getBytes(),StandardOpenOption.APPEND);
finalWrite = "";
}
}
out.close();
Log.log("Finished combineRecords");
finalValues = new FileSheet(outputFilepath,0);
return finalValues;
}
当前的CombineRecords方法类似于
streams.get(ordinal).skip(i).findFirst().get();
我已经尝试过bufferedwriters和files.write,它们创建文件3的时间都差不多,都是在1:30分钟的范围内,但是我不确定瓶颈是在读写方面
我正在使用的样本文件目前有36,000条记录,但是我将使用的实际文件为〜650,000,因此采取1625秒(如果线性缩放)对于此操作是完全不可行的
编辑:我修改了代码,只打开了一次文件,而不是每次迭代,但是现在我跳到第n行时就关闭了流。 我认为通过执行{{1}}会返回一个新的流,而不是跳过然后关闭该流
编辑2:修改了代码以使用bufferedreaders而不是流,并且每读取1000行就向文件写入一次,这就确定了瓶颈正在读取,因为它仍然需要〜1:30来完成
答案 0 :(得分:1)
首先在没有循环的情况下使用+
运算符来结束字符串。但是,当您要在循环中合并字符串时,应使用StringBuilder
以获得更好的性能。
您可以改善的第二件事可以像下面这样写到文件末尾:
StringBuilder finalWrite = new StringBuilder();
for (int i = 0; i < toCombine.get(0).recordCount(); i++)
{
for (FileSheet j : toCombine)
{
int ordinal = toCombine.indexOf(j);
finalWrite.append(streams.get(ordinal).readLine());
if (toCombine.indexOf(j) != toCombine.size() - 1)
{
finalWrite.append(",");
}
else
{
finalWrite.append("\n");
}
}
}
Files.write(Paths.get(outputFilepath), finalWrite.toString().getBytes());