java編程思想 第十八章 新IO

 

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.charset.Charset;
import java.util.Arrays;

public class Ans {
    public static void main(String[] args) throws IOException {
        //test0();
        //test1();
        //test2();
        test3();
    }

    static void test0() throws IOException {
        //java 1.4版本使用了新IO提高性能,加入了通道(Channel),唯一與通道直接交互的緩衝器是ByteBuffer,由於是字節Buffer所以只能使用FileInputStream等,不能用FileReader
        FileChannel fco = new FileOutputStream("test").getChannel();
        FileChannel fci = new FileInputStream("test").getChannel();
        fco.write(ByteBuffer.wrap("sunsunsun".getBytes()));
        fco.close();
        ByteBuffer bf = ByteBuffer.allocate(1000);
        fci.read(bf);
        System.out.println(Arrays.toString(bf.array()));
        bf.rewind();                                                                    //將pos指針設爲指向0位置
        System.out.println("***"+bf.asCharBuffer().toString()+"***");                 //不能這樣,因爲存入和讀出的都是普通字節,需要編碼和解碼
        String encoding = System.getProperty("file.encoding");                          //需要這樣解碼
        System.out.println(Charset.forName(encoding).decode(bf));
    }

    static void test1() throws IOException {
        //在這裏我們演示文件之間的拷貝
        FileChannel fci = new FileInputStream("test").getChannel();
        FileChannel fco = new FileOutputStream("test2").getChannel();
        ByteBuffer bf = ByteBuffer.allocate(1024);
        while (fci.read(bf)!=-1) {
            bf.flip();                                  //flip將limit設爲pos,pos設爲0,準備讀取buffer
            fco.write(bf);                              //不指定位置的read和write都會相應的改變pos等指針
            bf.clear();                                 //清除
        }

        fci = new FileInputStream("test").getChannel();
        fco = new FileOutputStream("test2").getChannel();
        fci.transferTo(0,fci.size(),fco);                   //還有一種對接通道的方法
    }

    static void test2() {
        //可以將ByteBuffer轉換爲別的類型的視圖
        ByteBuffer bf = ByteBuffer.allocate(1024);
        bf.asDoubleBuffer().put(120333);
        System.out.println(bf.asDoubleBuffer().get());
        System.out.println(bf.asFloatBuffer().get());
    }

    static void test3() throws IOException {
        //內存映射文件可以讓一個大文件彷彿存在內存之中,這樣就可以大幅度簡化我們的操作
        MappedByteBuffer mbb = new RandomAccessFile("test","rw").getChannel().map(FileChannel.MapMode.READ_WRITE,0,10000);
        //另一點,就算是隻寫文件,在內存映射時也要用RandomAccessFile,不能用FileOutputStream
        for (int i = 0;i<10000;++i)
            mbb.put((byte)'x');
        for (int i = 100;i<133;++i)
            mbb.put(i,(byte)'t');
    }

    static void test4() throws IOException {
        //最簡單的文件加鎖
        FileOutputStream fos = new FileOutputStream("test");
        FileLock fl = fos.getChannel().tryLock();
        if (fl!=null)
            fl.release();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章