2023-09-23
原文作者:李林超 原文地址: https://www.lilinchao.com/archives/2092.html

将数据写入指定文件

    import lombok.extern.slf4j.Slf4j;
    
    import java.io.File;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.charset.StandardCharsets;
    import java.nio.file.StandardOpenOption;
    
    /**
     * Created by lilinchao
     * Date 2022/5/27
     * Description channel Demo
     */
    @Slf4j
    public class channelDemo01 {
        public static void main(String[] args) throws IOException {
    
            // 获得一个根据指定文件路径的读写权限文件通道
            FileChannel fileChannel = FileChannel.open(new File("datas/data.txt").toPath(), StandardOpenOption.WRITE,StandardOpenOption.READ);
            //获得一段有指定内容的缓冲区
            ByteBuffer source = ByteBuffer.wrap("helloWorld,Scala,Java".getBytes(StandardCharsets.UTF_8));
            ByteBuffer target = ByteBuffer.allocate(50);
            log.info("fileChannel.position():{}",fileChannel.position());
            //将缓冲区中的内容写入文件通道
            fileChannel.write(source);
            //通道大小
            log.info("fileChannel.position():{}", fileChannel.position());
            //设置读写位置
            fileChannel.position(0);
            //将通道中的内容写到空缓冲区
            fileChannel.read(target);
            //转换缓冲区读写模式
            target.flip();
            log.info("target:{}", new String(target.array(), 0, target.limit()));
            //关闭资源
            fileChannel.close();
        }
    }

数据读写

    import lombok.extern.slf4j.Slf4j;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.charset.StandardCharsets;
    
    /**
     * Created by lilinchao
     * Date 2022/5/27
     * Description 数据读写
     */
    @Slf4j
    public class channelDemo02 {
        public static void main(String[] args) throws IOException {
            //获取输出流
            FileOutputStream outputStream = new FileOutputStream("datas/data.txt");
            //根据输出流获得一个"写"权限的通道
            FileChannel outChannel = outputStream.getChannel();
            //获得一个有指定内容的缓冲区
            ByteBuffer source = ByteBuffer.wrap("HelloWorld".getBytes(StandardCharsets.UTF_8));
            //将缓冲区内容写入到通道
            outChannel.write(source);
    
            //获取输入流
            FileInputStream fileInputStream = new FileInputStream("datas/data.txt");
            //根据输入流获得一个"读"权限的通道
            FileChannel inChannel = fileInputStream.getChannel();
            //获得一个空内容的缓冲区
            ByteBuffer target = ByteBuffer.allocate(50);
            //将通道中的内容读到缓冲区
            inChannel.read(target);
            //转换缓冲区读写模式
            target.flip();
            //读出缓冲区中的内容
            log.info("target:{}", new String(target.array(), 0, target.limit()));
    
            //关闭资源
            outChannel.close();
            inChannel.close();
        }
    }

超过 2g 大小的文件传输

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.channels.FileChannel;
    
    /**
     * Created by lilinchao
     * Date 2022/5/27
     * Description 超过 2g 大小的文件传输
     */
    public class TestFileChannelTransferTo {
        public static void main(String[] args) {
            try (
                    FileChannel from = new FileInputStream("datas/data.txt").getChannel();
                    FileChannel to = new FileOutputStream("datas/to.txt").getChannel()
            ) {
                // 效率高,底层会利用操作系统的零拷贝进行优化
                long size = from.size();
                // left 变量代表还剩余多少字节
                for (long left = size; left > 0; ) {
                    System.out.println("position:" + (size - left) + " left:" + left);
                    left -= from.transferTo((size - left), left, to);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

FileChannel Demo 改变子缓冲区内容

    import java.io.File;
    import java.io.RandomAccessFile;
    import java.nio.ByteBuffer;
    import java.nio.IntBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.charset.StandardCharsets;
    
    /**
     * Created by lilinchao
     * Date 2022/5/27
     * Description FileChannel Demo
     */
    public class TestFileChannelDemo {
        public static void main(String[] args) throws Exception {
    //        testSlice();
    //        testFileChannel();
    //        testIntBuffer();
    //        writeFileChannel();
            testFileChannelTransfer();
        }
    
        /**
         * 切片:改变缓冲区的内容
         */
        public static void testSlice() throws Exception {
    
            //获取通道
            RandomAccessFile accessFile = new RandomAccessFile(new File("datas/data.txt"),"rw");
            FileChannel channel = accessFile.getChannel();
    
            //缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(9);
            //将数据读入缓冲区
            channel.read(buffer);
            buffer.position(3);
            buffer.limit(7);
    
            //用于创建一个新的字节缓冲区,其内容是给定缓冲区内容的共享子序列。
            ByteBuffer slice = buffer.slice();
            //改变子缓冲区内容
            for (int i = 0;i<slice.capacity();i++){
                byte b = slice.get(i);
                b *=2;
                slice.put(i,b);
            }
            buffer.position(0);
            buffer.limit(buffer.capacity());
            while (buffer.remaining() > 0){
                System.out.println(buffer.get());
            }
        }
    
        /**
         * fileChannel读文件
         */
        public static void testFileChannel() throws Exception {
    
            RandomAccessFile accessFile = new RandomAccessFile(new File("datas/data.txt"),"rw");
            FileChannel channel = accessFile.getChannel();
            //缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            //将数据读入缓冲区
            //返回的值表示读取到的字节数,如果读到了文件末尾,返回值为 -1
            int read = channel.read(buffer);
            while (read != -1){
                System.out.println("file长度:"+read);
                buffer.flip();
                while (buffer.hasRemaining()){
                    System.out.println((char) buffer.get());
                }
                //切换到写模式,position=0,limit变为capacity
                buffer.clear();
                read = channel.read(buffer);
            }
            accessFile.close();
            System.out.println("end");
        }
    
        /**
         * intBuffer
         */
        public static void testIntBuffer(){
            //用于在现有缓冲区旁边分配一个新的int缓冲区
            IntBuffer buffer = IntBuffer.allocate(1024);
            buffer.put(new int[]{1,2,3});
            buffer.flip();
            while (buffer.hasRemaining()){
                System.out.println(buffer.get());
            }
        }
        /**
         * fileChannel写文件
         */
        public static void writeFileChannel() throws Exception {
            RandomAccessFile rw = new RandomAccessFile("datas/data.txt","rw");
            FileChannel channel = rw.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            buffer.put("欢迎来到李林超博客!!!".getBytes(StandardCharsets.UTF_8));
            buffer.flip();
            while (buffer.hasRemaining()){
                channel.write(buffer);
            }
            channel.close();
        }
    
        //fileChannel通道之间传输
        public static void testFileChannelTransfer() throws Exception {
            RandomAccessFile accessFileA = new RandomAccessFile("datas/data.txt","rw");
            FileChannel channelFrom = accessFileA.getChannel();
            RandomAccessFile accessFileB = new RandomAccessFile("datas/dataB.txt","rw");
            FileChannel channelTo = accessFileB.getChannel();
            //from 的内容传输到 channelTo
            channelTo.transferFrom(channelFrom,0,channelFrom.size());
            accessFileA.close();
            accessFileB.close();
        }
    }

附参考文章链接:

https://blog.csdn.net/qq_38745846/article/details/120786800

https://juejin.cn/post/7030802468552474637

阅读全文