控制台程序,本例读取Java基础之写文件部分(PrimesToFile2)写入的Primes.txt。
方法二:设置一个任意容量的、大小合适的字节缓冲区并且使用来自文件的字节进行填充。然后整理出缓冲区中所有的内容。这种方式的问题是:缓冲区的内容可能会在读取文件的一个数据项时半途而断。这样一来,就必须做一些工作对此进行检测并且找出下一步要做的工作,但是这比第一种方式更加有效,因为这极大减少了用于读取整个文件所需的读操作数目。
本例的关键是缓冲区类提供的compact()方法,即压缩缓冲区。
1 import java.nio.file.*; 2 import java.nio.channels.ReadableByteChannel; 3 import java.io.IOException; 4 import java.nio.ByteBuffer; 5 6 public class ReadPrimesMixedData2 { 7 8 public static void main(String[] args) { 9 Path file = Paths.get(System.getProperty("user.home")).resolve("Beginning Java Struff").resolve("primes.txt"); 10 if(!Files.exists(file)) { 11 System.out.println(file + " does not exist. Terminating program."); 12 System.exit(1); 13 } 14 15 try(ReadableByteChannel inCh = Files.newByteChannel(file)) { 16 ByteBuffer buf = ByteBuffer.allocateDirect(256); 17 buf.position(buf.limit()); // Set the position for the loop operation 18 int strLength = 0; // Stores the string length 19 byte[] strChars = null; // Array to hold the bytes for the string 20 21 while(true) { 22 if(buf.remaining() < 8) { // Verify enough bytes for string length 23 if(inCh.read(buf.compact()) == -1) 24 break; // EOF reached 25 buf.flip(); 26 } 27 strLength = (int)buf.getDouble(); // Get the string length 28 29 // Verify enough bytes for complete string 30 if(buf.remaining() < 2*strLength) { 31 if(inCh.read(buf.compact()) == -1) { 32 System.err.println("EOF found reading the prime string."); 33 break; // EOF reached 34 } 35 buf.flip(); 36 } 37 strChars = new byte[2*strLength]; // Array for string bytes 38 buf.get(strChars); // Get the bytes 39 40 if(buf.remaining() < 8) { // Verify enough bytes for prime value 41 if(inCh.read(buf.compact()) == -1) { 42 System.err.println("EOF found reading the binary prime value."); 43 break; // EOF reached 44 } 45 buf.flip(); 46 } 47 48 System.out.printf("String length: %3s String: %-12s Binary Value: %3d%n", 49 strLength, ByteBuffer.wrap(strChars).asCharBuffer(),buf.getLong()); 50 } 51 52 System.out.println(" EOF reached."); 53 54 } catch(IOException e) { 55 e.printStackTrace(); 56 } 57 } 58 }