天天看點

JAVA NIO(New IO)使用和傳統IO使用二、特立獨行的RandomAccessFile三、NIO

一、傳統IO流類結構設計:

JAVA NIO(New IO)使用和傳統IO使用二、特立獨行的RandomAccessFile三、NIO

傳統IO設計是面向流(位元組流或字元流)的,部分是有緩沖區的,對于沒有緩沖區的流,為了提高效率,是需要我們自行使用緩沖區的。

ByteArrayOutputStream 内部用一個自動增長byte[]将資料儲存起來,即使流被關閉,資料還是可以通路的,适合多次通路流的場景,一般輸入流隻能讀一次。

ByteArrayInputStream 内部用一個自動增長的byte[]将資料儲存起來,即使流被關閉,資料還是可以通路的,适合多次通路流的場景,一般輸入流隻能讀一次。

BufferedOutputStream 具備緩沖能力的輸出流

BufferedInputStream 具備緩沖能力的輸入流

/**
 * 輸入流拷貝到輸出流
 *
 * @throws Exception
 */
void testCopyStream() throws Exception {
    FileInputStream fileInputStream = new FileInputStream("img/a.jpg");
    FileOutputStream fileOutputStream = new FileOutputStream("img/a2.jpg");
    byte[] buf = new byte[1024];
    int len;
    // 這裡的緩沖對輸入和輸出流都有作用
    while ((len = fileInputStream.read(buf)) != -1) {
        fileOutputStream.write(buf, 0, len);
    }
    fileOutputStream.flush();
    fileInputStream.close();
    fileOutputStream.close();
}

/**
 * ByteArrayOutputStream功效,能将整個流内容存起來,後續繼續構造一個輸出或輸入流重複使用,一般輸入流隻能讀取一次,想重複使用需要自己儲存内容
 * 輸入流轉換成String
 *
 * @throws Exception
 */
void testByteArrayStream() throws Exception {
    FileInputStream fileInputStream = new FileInputStream("text/a.txt");
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(10240);
    byte[] buf = new byte[2048];
    int len;
    while ((len = fileInputStream.read(buf)) != -1) {
        byteArrayOutputStream.write(buf, 0, len);
    }
    byteArrayOutputStream.flush();
    String content = byteArrayOutputStream.toString("UTF-8");
    System.out.println(content);
}

void testBufferedStream() throws Exception{
    FileInputStream fis = new FileInputStream("test");
    BufferedInputStream bis = new BufferedInputStream(fis);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // 讀取bis流中的下一個位元組
    int c = bis.read();
    while (c != -1) {
        baos.write(c);
        c = bis.read();
    }
    bis.close();
    byte retArr[] = baos.toByteArray();
}
           

二、特立獨行的RandomAccessFile

Java中有一個操作檔案随機任意位置讀寫的類型,JDK1.0就有了,他就是RandomAccessFile。他并沒有性能上的優勢。

三、NIO

0、作業系統在與外部裝置進行互動時,是需要發生系統中斷的,此時使用者程序(線程)會被挂起,核心操作完成後才會恢複使用者程式,其中,使用者程式是不直接與外部裝置互動,使用者程式和核心互動,核心與外部裝置互動。

1、Java NIO中主要元件是Selector、Channel、Buffer,看到Selector就知道Java NIO的IO模型多路複用。

2、NIO的3個元件中使用者程式設計最多的是Buffer,Buffer就是使用者程式緩沖區的接口,背後他會與核心緩沖區進行資料互動,是以讀、寫操作就完全依賴Buffer的使用了。

3、建立Buffer時需要指定緩沖區的大小,這個大小最好比實際傳輸的消息大小略大一些。

4、Buffer有個flip()反轉方法,用來反轉Buffer的讀、寫狀态,為什麼需要這個方法?因為當你從Channel中讀取資料時,對Buffer來說是寫狀态,Buffer被寫完以後,需要從Buffer中讀取到使用者的業務程式中,這個時候對Buffer來說是讀狀态,需要調用flip()反轉,是以由此看來,flip()方法一定不能少。

Channel實作,包含了檔案IO和網絡IO
FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel

Buffers實作,包含了各個資料類型
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
           
// 讀檔案    
public static void readFile(File file) throws Exception{
    RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
    FileChannel channel = randomAccessFile.getChannel();
    // 傳統IO用BufferedReader
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    channel.read(buffer);
    byte[] b = buffer.array();
    System.out.println(new String(b));
    channel.close();
    randomAccessFile.close();
}