NIO之FileChannel操作示例

1. 写文件操作

/**
 * 写文件
 */
public class FileChannelTest {
    public static void main(String[] args) throws IOException {
        String str = "test file channel, 测试file channel";
        // 创建一个输出流
        FileOutputStream fileOutputStream = new FileOutputStream("D://nio.txt");
        // 得到file channel
        FileChannel fileChannel = fileOutputStream.getChannel();
        // 创建一个缓存buffer

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        // 将数据放到buffer中
        byteBuffer.put(str.getBytes());

        // 反转, read -> write
        byteBuffer.flip();

        // 将buffer中的数据写入到file channel
        fileChannel.write(byteBuffer);

        fileChannel.close();
    }
}

2. 读文件操作

/**
 * 读文件
 */
public class FileChannelTest02 {
    public static void main(String[] args) throws Exception {
        File file = new File("D://nio.txt");
        // 创建一个输入流
        FileInputStream fileInputStream = new FileInputStream(file);
        // 得到file channel
        FileChannel fileChannel = fileInputStream.getChannel();
        // 创建一个缓存buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());
        // 将file channel 中的数据读入到buffer中
        fileChannel.read(byteBuffer);
        byte[] array = byteBuffer.array();
        String data = new String(array);
        System.out.println(data);
        fileChannel.close();
    }
}

 

3. 使用FileChannel拷贝文件

/**
 * 文件的拷贝,用一个buffer完成的读写
 */
public class CopyFileTest03 {
    public static void main(String[] args) throws Exception {
        FileInputStream fileInputStream = new FileInputStream("src/1.txt");
        FileChannel channel = fileInputStream.getChannel();

        FileOutputStream fileOutputStream = new FileOutputStream("2.txt");
        FileChannel channel1 = fileOutputStream.getChannel();

        ByteBuffer buffer = ByteBuffer.allocate(1024);
        /**
         * 下面的代码存在bug , 只会读写一次,如果文件内容大于1024, 后面的内容就会丢失
         */
//        // 将channel中的数据读到buffer中
//        channel.read(buffer);
//        buffer.flip();
//        // 将缓冲区的数据读取到通道中
//        channel1.write(buffer);

        while (true) {
            // 如果调用clear()方法,会出现死循环, read == 0 .
            buffer.clear();
            int read = channel.read(buffer);
            System.out.println(read);
            if (read == -1) {
                break;
            }
            // 数据从buffer中写到channel中
            buffer.flip();
            channel1.write(buffer);
        }
        fileInputStream.close();
        fileOutputStream.close();


    }
}

 

4. 调用FileChannel的API完成文件拷贝

/**
 * 使用transferFrom 和 transferTo 拷贝文件
 *
 */
public class CopyFileTest04 {
    public static void main(String[] args) throws Exception {
        FileInputStream fileInputStream = new FileInputStream("1.jpg");
        FileChannel inputStreamChannel = fileInputStream.getChannel();
        FileOutputStream fileOutputStream = new FileOutputStream("2.jpg");
        FileChannel outputStreamChannel = fileOutputStream.getChannel();
        // 文件拷贝
//        outputStreamChannel.transferFrom(inputStreamChannel, 0, inputStreamChannel.size());
        inputStreamChannel.transferTo(0, inputStreamChannel.size(), outputStreamChannel);
        // 关闭通道和流
        fileInputStream.close();
        fileOutputStream.close();

    }
}

 

注意:

  读写同一个buffer时,需要flip();

  读写1次buffer之后,需要clear(), 将buferr复位

 

上一篇:灵魂一击!Netty系列笔记之Reactor模式(建议收藏)


下一篇:JavaIO四大模型:NIO(IO多路复用)