ByteBuffer按行處理資料(readline)

壹頁書發表於2014-05-07
NIO沒有BufferedReader這樣讀取行的方法。
可以查詢ByteBuffer最後一個換行符,在換行符之後的資料,重新放回ByteBuffer


  1. import java.io.FileInputStream;
  2. import java.io.IOException;
  3. import java.io.UnsupportedEncodingException;
  4. import java.nio.ByteBuffer;
  5. import java.nio.channels.FileChannel;
  6. import java.nio.charset.Charset;

  7. interface Callback {
  8.     void action(String line);
  9. }

  10. public class NIOReadline {
  11.     private int buffersize;
  12.     private Charset charset ;
  13.     private Callback callback;
  14.     private FileChannel channel;
  15.     ByteBuffer buffer ;

  16.     public NIOReadline(String file, Callback callback) throws UnsupportedEncodingException, IOException {
  17.         this(file,callback,200,Charset.defaultCharset().displayName());
  18.     }
  19.     
  20.     public NIOReadline(String file, Callback callback,int bufferSize,String charsetName) throws UnsupportedEncodingException, IOException {
  21.         charset=Charset.forName(charsetName);
  22.         buffersize=bufferSize;
  23.         channel = new FileInputStream(file).getChannel();
  24.         buffer=ByteBuffer.allocate(bufferSize);
  25.         this.callback=callback;
  26.         action();
  27.     }

  28.     private void action() throws UnsupportedEncodingException, IOException {
  29.         while (channel.read(buffer) > 0) {
  30.             buffer.flip();
  31.             byte[] data = new byte[buffersize];
  32.             // 陣列最後一個可用資料
  33.             int last = buffer.limit() - 1;
  34.             buffer.get(data, 0, buffer.limit());
  35.             buffer.compact();
  36.             // 找最後一個換行符
  37.             int i = last;
  38.             while (data[i] != (byte) '\n') {
  39.                 i = i - 1;
  40.                 // 如果沒有換行符,直接退出,可能是最後一行
  41.                 if (i < 0) {
  42.                     break;
  43.                 }
  44.             }

  45.             if (i > 0) {
  46.                 // 如果有換行符
  47.                 action(new String(data, 0, i + 1, charset));

  48.                 while (i < last) {
  49.                     buffer.put(data[i + 1]);
  50.                     i++;
  51.                 }
  52.             } else {
  53.                 action(new String(data, 0, buffer.limit(), charset));
  54.             }
  55.         }
  56.         channel.close();
  57.     }

  58.     private void action(String str) {
  59.         String[] data = str.split("\n");
  60.         for (String line : data) {
  61.             callback.action(line);
  62.         }
  63.     }

  64.     public static void main(String[] args) throws UnsupportedEncodingException, IOException {
  65.         NIOReadline r=new NIOReadline("C:\\Users\\new\\Desktop\\test.sql", new Callback() {
  66.             
  67.             @Override
  68.             public void action(String line) {
  69.                 System.out.print(line);
  70.             }
  71.         });
  72.     }
  73. }
這個方法可以解決使用ByteBuffer造成的文字截斷問題。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1155749/,如需轉載,請註明出處,否則將追究法律責任。

相關文章