2012-03-29 76 views
0

我試圖將一個非常大的文件寫入另一個非常大的文件。我在filechannel寫入行收到此錯誤,但我不確定原因。我認爲這是因爲我很長時間才走出數據類型的限制,但長達9,223,372,036,854,775,807,而我最多隻能達到5,372,896,745。任何想法爲什麼發生這種情況? MappedByteBuffer有一些限制嗎?對於較小的文件,這種情況不會發生,並且我還沒有遇到在Java桌面應用程序中使用相同代碼的任何問題。 (只發生在Android上)Android NIO - java.io.IOException:對於定義的數據類型,值太大

File f1 = new File(filename1); 

FileChannel fic, foc; 
long fsize; 
MappedByteBuffer mBUf; 

FileOutputStream out = new FileOutputStream(f1,true); 
foc = out.getChannel(); 

File f2 = new File(filename2); 
FileInputStream in = new FileInputStream(f2); 

fic = in.getChannel(); 
fsize = fic.size(); 

for (long b = 0; b < fsize; b += 65536) 
{ 
    if (fsize - b < Resource.MEMORY_ALLOC_SIZE) 
     mBUf = fic.map(FileChannel.MapMode.READ_ONLY, b, fsize - b); 
    else 
     mBUf = fic.map(FileChannel.MapMode.READ_ONLY, b, Resource.MEMORY_ALLOC_SIZE); 
    foc.write(mBUf); //ERROR HERE! 
}    

fic.close(); 
in.close(); 
foc.close(); 
out.close(); 

任何想法/反饋讚賞!

回答

3

MappedByteBuffer有一些限制嗎?

當然有。它受限於可用的虛擬內存以用於啓動,之後受到虛擬地址空間的限制。

對於這項任務,您應該使用transferTo()而不是MappedByteBuffers,,因爲沒有協議來處理後者佔用的虛擬地址空間。

+0

我試着去transferTo路線,但它仍然拋出相同的錯誤。 – azdragon2 2012-03-30 21:28:27

+1

@ azdragon2您將不得不嘗試較小的傳輸大小。指定超過大約1兆字節沒有優勢。通過'transferTo()'API的結構,你必須把它放在一個循環中,因爲它不保證傳輸請求的數量。所以要做到這一點,並調整'大小'參數來理智。 – EJP 2012-03-31 00:36:39

-1

不幸的是,Long在32位系統上並沒有那麼高(我相信Android是因爲它沒有超過4Gb的RAM)。因此,Android上無符號長整型的最大長度爲4,294,967,295,這意味着您超出了限制。

+0

我不認爲這是數據類型長在我的for循環拋出的錯誤,但你送我在正確的道路上。顯然寫入一個2097215 KB或〜2.00006 GB的文件的通道是拋出這個錯誤。我總是覺得NIO並沒有將整個文件加載到內存中?我將不得不尋找替代路徑,感謝您的幫助! – azdragon2 2012-03-30 21:32:30

+0

@ azdragon2一個'MappedByteBuffer' *將整個文件映射到內存中。看到Javadoc。你不想那麼做! – EJP 2012-03-31 00:23:37

+2

「長」*絕對*在32位系統上高。 「長」的大小不取決於體系結構。在NIO實現中可能存在限制,但是*並不意味着'long'本身的大小在Android上有任何不同。 – 2012-05-01 05:52:21

相關問題