2023-09-23  阅读(1)
原文作者:李林超 原文地址: 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


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文