2011-06-28 48 views
2

我有一个非常大的文件(可能是1G),我想以相反的顺序(以Java)创建一个新文件。 例如:读取并按相反顺序写入文件 - Java

Original file: 

This is the first line 
This is the 2nd line 
This is the 3rd line 

The reversed file: 

This is the 3rd line 
This is the 2nd line 
This is the first line 

由于文件是非常大的,一次加载整个文件到内存和反向排序可能有问题(有是我可以使用内存的限制)。 我如何在Java中实现这一点?

谢谢

+0

这让我想起了一个(可能是面试)问题(找不到它,认为它在http://programmers.stackexchange.com某处),你必须在100Gb中对行进行排序只使用1Gb RAM的120Gb磁盘上的文本文件。 – Qwerky

回答

6

没什么很直接的,恐怕。但是您可以轻松创建一些(比如说)ReverseBufferedRead类,包装RandomAccessFile。请参阅here

0

我会假设你知道如何读取文件。我建议你这样做的一种方式是使用泛型类型字符串的ArrayList。所以你阅读文件的每一行并将其存储在该列表中。阅读完成后,将列表打印出来或做任何你想做的事情。

只是写东西,可能是帮助在这里:http://pastebin.com/iWTVrAvm

+0

谢谢,但这里的问题是我无法将整个文件加载到内存中,因此我无法使用此解决方案。 – Liz

1

读取文件线由行以相反的顺序是从根本上棘手。

这不是如果你有一个固定宽度的编码不好。如果你有一个可变宽度编码,你可以检测到第一个字节(例如UTF-8),这是可行的。如果编码是可变宽度,没有明确的边界确定方法(或者它使用“移位”),那么实际上不可能有效地进行。

我在C#in another question中有一个实现,但它将花费相当多的努力将其移植到Java。

5

通过几百行块读取文件,颠倒块的行顺序并将它们写入临时文件。然后按相反顺序加入临时文件并清理。

换句话说,使用磁盘而不是内存。

0

阅读使用RandomAccessFile - 使用randomAccesFile.length()的文件中的位置,并使用BufferedWriter

+1

在RandomAccessFile的情况下,你是什么意思“绕回缓冲类的内存问题”? RandomAccessFile无法封装BufferedReader(当然,我无法读取BufferedReader ...),所以我不确定你在这里的含义。 – Liz

+0

你说得对。我编辑了我的回复以删除该行。 –

1

写如果使用RandomAccessFile的像leonbloy建议您可以使用FileChannel

跳到文件的末尾,然后您可以读取该行并将其写入另一个文件。

这里有在Java教程一个简单的例子:example

2

我建议作出的RandomAccessFile的输出,并使用setLength(),使其适当大小。

然后开始扫描原始文件并将其从RandomAccessFile的末尾开始以相反的顺序写出。

爪哇肥胖型伪:

out.seek(size_of_out_file); //seek to end 
RandomAccessFile out = new RandomAccessFile("out_fname", "rw"); 
out.setLength(size_of_file_to_be_reversed) 
File in = new File ("in_fname"); 
while (hasMoreData(in)){ 
    String chunk = in.readsize(); 
    out.seekBackwardsBy(chunk.length()); 
    out.write(chunk.reverse); 
    out.seekBackwardsBy(chunk.length()); 
}