2011-06-28 83 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()); 
}