2017-07-24 44 views
-1

我試圖讀取ByteBuffer塊中的文件,然後將其存儲到ByteBuffer列表中,然後在某些操作之後按順序讀取這些ByteBuffer塊重建文件。問題在於寫入輸出文件通道的位置不增加。 我不想使用字節數組,因爲它們的長度是固定的,文件重建不能正常工作。 所以我想知道如何增加文件寫入通道位置的大小,或任何其他方式來做這個操作。示例代碼將不勝感激。 這裏是我的代碼片段,以較小長度的字節緩衝區塊數讀寫文件

file = new File(fileName); // hello.txt - 20 MB size 
fis = new FileInputStream(file); 
inChannel = fis.getChannel(); 
double maxChunkSequenceNoFloat = ((int)inChannel.size())/chunkSize; 
int maxChunkSequenceNo = 1; 
if(maxChunkSequenceNoFloat%10 > 0) { 
    maxChunkSequenceNo = ((int)maxChunkSequenceNoFloat)+1; 
} else if(maxChunkSequenceNoFloat%10 < 0) { 
    maxChunkSequenceNo = 1; 
} else { 
    maxChunkSequenceNo = (int)maxChunkSequenceNoFloat; 
} 
maxChunkSequenceNo = (maxChunkSequenceNo == 0) ? 1 : maxChunkSequenceNo;    
ByteBuffer buffer = ByteBuffer.allocate(chunkSize); 
buffer.clear(); 

while(inChannel.read(buffer) > 0) { 
    buffer.flip(); 
    bufferList.add(buffer); 
    buffer.clear(); 
    chunkSequenceNo++; 
} 
maxChunkSequenceNo = chunkSequenceNo; 

// write 
File file1 = new File("hello2.txt") ; 
buffer.clear(); 
FileOutputStream fos = new FileOutputStream(file1); 
FileChannel outChannel = fos.getChannel(); 
chunkSequenceNo = 1; 
for(ByteBuffer test : bufferList) { 
    writeByteCount += outChannel.write(test); 
    //outChannel.position() += writeByteCount;' 
    System.out.println("main - channelPosition: "+outChannel.position() 
         +" tempBuffer.Position: "+test.position() 
         +" limit: "+test.limit() 
         +" remaining: "+test.remaining() 
         +" capacity: "+test.capacity());    
} 
BufferedReader br = new BufferedReader(new FileReader(file1)); 
String line = null; 
while ((line = br.readLine()) != null) { 
    System.out.println(line); 
} 
outChannel.close(); 
fos.close(); 

ByteBuffer的立場是正確的,但outChannel位置保持在1048這是塊的大小。

+0

保持簡單和(部分)使用字節數組。 FileReader使用默認的平臺編碼。 –

+0

這不僅僅是關於我的代碼,而是處理我的數據的類需要ByteBuffers,所以我在問題中明確表示,直接使用字節數組是毫無疑問的。 – andi99

+0

你只使用一個緩衝區,所以你的代碼根本不符合你的描述。 – EJP

回答

1

下面確實會根據請求維護一個ByteBuffers列表。

String fileName = "hello.txt"; 
final int chunkSize = 256; 
List<ByteBuffer> bufferList = new ArrayList<>(); 
Path path = Paths.get(fileName); 
try (SeekableByteChannel inChannel = Files.newByteChannel(path, 
     EnumSet.of(StandardOpenOption.READ))) { 
    long size = inChannel.size(); 
    while (size > 0) { 
     ByteBuffer buffer = ByteBuffer.allocate(chunkSize); 

     int nread = inChannel.read(buffer); 
     if (nread <= 0) { 
      break; 
     } 
     buffer.flip(); 
     bufferList.add(buffer); 
     size -= nread; 
    } 
} 

// write 
Path file1 = Paths.get("hello2.txt") ; 
try (SeekableByteChannel outChannel = Files.newByteChannel(file1, 
     EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE))) { 
    for (ByteBuffer buffer : bufferList) { 
     int nwritten = outChannel.write(buffer); 
    } 
} 

試用資源負責關閉頻道/文件。 文件(實用功能)和路徑(比文件更通用)很有用。

當有一個chunkSize限制時,需要添加一個ByteBuffer的新實例。 (所以也可能會添加底層字節數組。)

最好不要使用浮點,即使在這裏。

+0

謝謝你的作品。我認爲bytebuffer不能被重用,它必須被再次實例化。 – andi99