java 给文件排序_java – 如何排序N个文件

根据这个答案 – >

我只需要N个已经排序的磁盘上的文件的Merge功能,

我想将它们分成一个大文件我的限制是内存不超过内存中的K行(K public void run() {

try {

System.out.println(file1 + " Started Merging " + file2 );

FileReader fileReader1 = new FileReader(file1);

FileReader fileReader2 = new FileReader(file2);

//......TODO with N ?? ......

FileWriter writer = new FileWriter(file3);

BufferedReader bufferedReader1 = new BufferedReader(fileReader1);

BufferedReader bufferedReader2 = new BufferedReader(fileReader2);

String line1 = bufferedReader1.readLine();

String line2 = bufferedReader2.readLine();

//Merge 2 files based on which string is greater.

while (line1 != null || line2 != null) {

if (line1 == null || (line2 != null && line1.compareTo(line2) > 0)) {

writer.write(line2 + "\r\n");

line2 = bufferedReader2.readLine();

} else {

writer.write(line1 + "\r\n");

line1 = bufferedReader1.readLine();

}

}

System.out.println(file1 + " Done Merging " + file2 );

new File(file1).delete();

new File(file2).delete();

writer.close();

} catch (Exception e) {

System.out.println(e);

}

}

问候,

解决方法:

你可以使用这样的东西

public static void mergeFiles(String target, String... input) throws IOException {

String lineBreak = System.getProperty("line.separator");

PriorityQueue> lines

= new PriorityQueue<>(Map.Entry.comparingByKey());

try(FileWriter fw = new FileWriter(target)) {

String header = null;

for(String file: input) {

BufferedReader br = new BufferedReader(new FileReader(file));

String line = br.readLine();

if(line == null) br.close();

else {

if(header == null) fw.append(header = line).write(lineBreak);

line = br.readLine();

if(line != null) lines.add(new AbstractMap.SimpleImmutableEntry<>(line, br));

else br.close();

}

}

for(;;) {

Map.Entry next = lines.poll();

if(next == null) break;

fw.append(next.getKey()).write(lineBreak);

final BufferedReader br = next.getValue();

String line = br.readLine();

if(line != null) lines.add(new AbstractMap.SimpleImmutableEntry<>(line, br));

else br.close();

}

}

catch(Throwable t) {

for(Map.Entry br: lines) try {

br.getValue().close();

} catch(Throwable next) {

if(t != next) t.addSuppressed(next);

}

}

}

请注意,与您的问题中的代码不同,此代码处理标题行.与原始代码一样,它将删除输入行.如果不是这样,您可以删除DELETE_ON_CLOSE选项并简化整个阅读器构造

BufferedReader br = new BufferedReader(new FileReader(file));

它拥有与文件一样多的内存行.

原则上,可以在内存中保留较少的线串,在需要时重新读取它们,这对于可疑的少量保存来说将是性能灾难.例如.由于您有N个文件名,因此在调用此方法时,您在内存中已经有N个字符串.

但是,当您想要不惜一切代价减少同时保留的行数时,您只需使用问题中显示的方法即可.将前两个文件合并到一个临时文件中,将该临时文件与第三个文件合并到另一个临时文件,依此类推,直到将临时文件与最后一个输入文件合并到最终结果.然后你在内存中最多有两个线串(K == 2),比操作系统用于缓冲的内存节省更少,试图减轻这种方法的可怕性能.

同样,您可以使用上面显示的方法将K文件合并到一个临时文件中,然后将临时文件与下一个K-1文件合并,依此类推,直到将临时文件与剩余的K-1或更少文件合并为止最终结果是,在K <1的情况下进行存储器消耗缩放. N.这种方法允许调整K以使其具有合理的N比率,以便将速度换成记忆.我认为,在大多数实际情况中,K == N将会正常工作.

标签:java,algorithm

来源: https://codeday.me/bug/20190827/1745173.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值