首页 > 其他分享 >NIO操作文件读写

NIO操作文件读写

时间:2024-06-17 19:00:33浏览次数:19  
标签:文件 java NIO buffer 读写 file import ByteBuffer public

第一章

第一节,Buffuer

案例一  从buffur 读出数据,

创建了一个 FileInputStream 对象,并通过调用 getChannel() 方法获取了与之关联的 FileChannel。然后,

我们创建了一个 ByteBuffer,并使用 channel.read(buffer) 方法从文件中读取数据到缓冲区。最后,我们通过循环将缓冲区中的数据打印出来。

package cn.itcast.netty.c1;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestByteBuffer {
    public static void main(String[] args) {
        // 使用 FileChannel 从文件中读取数据到 ByteBuffer
        try (FileChannel channel = new FileInputStream("data.txt").getChannel()) { // 准备缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(10);
            // 从 channel 读取数据,向 buffer 写入
            channel.read(buffer);
            // 打印 buffer 的内容
            buffer.flip(); // 切换到读模式
            while (buffer.hasRemaining()) {
                System.out.print((char) buffer.get());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
读Buffuer 读数据

读数据可以通过判断一下还有没有数据

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestByteBuffer {
    public static void main(String[] args) {
        // 使用 FileChannel 从文件中读取数据到 ByteBuffer
        try (FileChannel channel = new FileInputStream("data.txt").getChannel()) { // 准备缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(10);
            while (true) {
                // 从 channel 读取数据,向 buffer 写入
                int len = channel.read(buffer);
                if (len == -1) { // 没有内容了
                    break;
                }
                // 打印 buffer 的内容
                buffer.flip(); // 切换至读模式
                while (buffer.hasRemaining()) { // 是否还有剩余未读数据
                    byte b = buffer.get();
                    System.out.println((char) b);
                }
                buffer.clear(); // 清空缓冲区以准备下一次读取
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

读写操作

import static cn.itcast.netty.c1.ByteBufferUtil.debugAll;

public class TestByteBufferReadWrite {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10); // 创建一个容量为10的ByteBuffer
        buffer.put((byte) 0x61); // 向buffer中放入字符'a' (ASCII码为0x61)
        debugAll(buffer); // 打印buffer的详细信息
        buffer.put(new byte[]{0x62, 0x63, 0x64}); // 向buffer中放入字节数组,包含字符'b', 'c', 'd'
        debugAll(buffer); // 打印buffer的详细信息

        System.out.println(buffer.get()); // 从buffer中读取一个字节并打印,这里会打印出'a'
        buffer.flip(); // 将buffer的模式从写模式切换到读模式
        System.out.println(buffer.get()); // 再次从buffer中读取一个字节并打印,这里会打印出'b'
        debugAll(buffer); // 打印buffer的详细信息
        buffer.compact(); // 清除buffer中的未读数据,已读数据之前的区域会被清空
        debugAll(buffer); // 打印buffer的详细信息
        buffer.put(new byte[]{0x65, 0x6F}); // 向buffer中放入字节数组,包含字符'e', 'o'
        debugAll(buffer); // 打印buffer的详细信息
    }
}

代码示例三 ,我们创建了一个 ByteBuffer,并使用 while 循环不断从文件中读取数据到缓冲区。当 channel.read(buffer) 返回 -1 时,表示文件已经读取完毕

,我们跳出循环。接下来,我们通过循环将缓冲区中的数据逐个打印出来。在每次循环结束时,我们使用 buffer.clear() 方法清空缓冲区,

以便下次读取。如果在读取过程中发生任何 IOException,我们会捕获异常并打印堆栈跟踪。

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestByteBuffer {
    public static void main(String[] args) {
        // 使用 FileChannel 从文件中读取数据到 ByteBuffer
        try (FileChannel channel = new FileInputStream("data.txt").getChannel()) { // 准备缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(10);
            while (true) {
                // 从 channel 读取数据,向 buffer 写入
                int len = channel.read(buffer);
                if (len == -1) { // 没有内容了
                    break;
                }
                // 打印 buffer 的内容
                buffer.flip(); // 切换至读模式
                while (buffer.hasRemaining()) { // 是否还有剩余未读数据
                    byte b = buffer.get();
                    System.out.println((char) b);
                }
                buffer.clear(); // 清空缓冲区以准备下一次读取
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

标记上一次打印位置

public static void main(String[] args) {
    // 假设buffer已经被填充了数据,并且已经flip切换到读模式
    System.out.println((char) buffer.get()); // 打印buffer中的第一个字符
    System.out.println((char) buffer.get()); // 打印buffer中的第二个字符
    
    buffer.mark(); // 在当前位置做一个标记
    
    System.out.println((char) buffer.get()); // 打印buffer中的第三个字符
    System.out.println((char) buffer.get()); // 打印buffer中的第四个字符
    
    buffer.reset(); // 将position重置到之前标记的位置
    
    System.out.println((char) buffer.get()); // 重新打印buffer中的第三个字符
    System.out.println((char) buffer.get()); // 重新打印buffer中的第四个字符
    
    // get(i)不会改变读索引的位置
    System.out.println((char) buffer.get(3)); // 直接获取索引为3位置的字符,不改变position
    
    debugAll(buffer); // 打印buffer的详细信息
}

分读同写

import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.io.RandomAccessFile;
import java.io.IOException;

public class ReadFileWithRandomAccess {
    public static void main(String[] args) {
        try (RandomAccessFile file = new RandomAccessFile("helloworld/3parts.txt", "rw")) {
            FileChannel channel = file.getChannel();
            
            // 分配三个ByteBuffer,用于存储从文件中读取的数据
            ByteBuffer a = ByteBuffer.allocate(3);
            ByteBuffer b = ByteBuffer.allocate(3);
            ByteBuffer c = ByteBuffer.allocate(5);
            
            // 从文件中读取数据到这三个ByteBuffer中
            channel.read(new ByteBuffer[]{a, b, c});
            
            // 确保每个ByteBuffer都处于读模式
            a.flip();
            b.flip();
            c.flip();
            
            // 打印每个ByteBuffer的内容
            debug(a);
            debug(b);
            debug(c);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 假设debug方法是用来打印ByteBuffer的内容
    private static void debug(ByteBuffer buffer) {
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get());
        }
        System.out.println();
    }
}

上一次没处理到下一次处理的示例‘

public class ByteBufferSplit {
    public static void main(String[] args) {
        ByteBuffer source = ByteBuffer.allocate(32);
        source.put("Hello, world\n" +
                   "I'm zhangsan\n" +
                   "How are you?\n".getBytes());
        split(source);
        source.put("What's your name?\n".getBytes());
        split(source);
    }

    private static void split(ByteBuffer source) {
        source.flip();
        while (source.hasRemaining()) {
            // 找到一条完整消息的结束符'\n'
            if (source.get(source.position()) == '\n') {
                int length = source.position() + 1 - source.position(); // 计算当前消息的长度
                
                // 把这条完整消息存入新的ByteBuffer
                ByteBuffer target = ByteBuffer.allocate(length);
                // 从source读取,向target写入
                for (int j = 0; j< length; j++) {
                    target.put(source.get());
                }
                target.flip(); // 确保target处于读模式
                // 这里可以处理或打印target的内容
                System.out.println(new String(target.array(), 0, target.limit()));
                source.position(source.position() + 1); // 移动source的位置到下一条消息的开始
            } else {
                source.position(source.position() + 1); // 如果不是结束符,移动到下一个位置继续查找
            }
        }
    }
}

第二章,文件读写

import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteBufferWriteExample {
    public static void main(String[] args) {
        // 创建一个ByteBuffer并分配空间
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        
        // 向ByteBuffer中存入数据
        buffer.put("This is some example text.\n".getBytes());
        
        // 切换ByteBuffer到读模式,准备写入操作
        buffer.flip();
        
        // 获取FileChannel,准备写入文件
        try (FileOutputStream fos = new FileOutputStream("output.txt");
             FileChannel channel = fos.getChannel()) {
            
            // 当ByteBuffer中还有数据时,循环写入FileChannel
            while (buffer.hasRemaining()) {
                channel.write(buffer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

复制文件

import java.nio.channels.FileChannel;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileTransferExample {
    public static void main(String[] args) {
        // 定义源文件的路径
        String from = "helloworld/data.txt";
        // 定义目标文件的路径
        String to = "helloworld/to.txt";
        // 记录文件传输操作开始的时间
        long start = System.nanoTime();
        
        try (
            // 创建读取源文件的FileChannel
            FileChannel fromChannel = new FileInputStream(from).getChannel();
            // 创建写入目标文件的FileChannel
            FileChannel toChannel = new FileOutputStream(to).getChannel();
        ) {
            // 使用transferTo方法将数据从源FileChannel传输到目标FileChannel
            fromChannel.transferTo(0, fromChannel.size(), toChannel);
        } catch (IOException e) {
            // 捕获并处理可能发生的IOException
            e.printStackTrace();
        } finally {
            // 记录文件传输操作结束的时间
            long end = System.nanoTime();
            // 计算并打印文件传输操作所用的时间,单位为毫秒
            System.out.println("transferTo 用时: " + (end - start) / 1_000_000.0 + " ms");
        }
    }
}

大文件读写

import java.nio.channels.FileChannel;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestFileChannelTransferTo {
    public static void main(String[] args) {
        try (
            // 创建读取源文件的FileChannel
            FileChannel from = new FileInputStream("data.txt").getChannel();
            // 创建写入目标文件的FileChannel
            FileChannel to = new FileOutputStream("to.txt").getChannel();
        ) {
            // 获取源文件的大小
            long size = from.size();
            // left变量代表还剩余多少字节未传输
            for (long left = size; left > 0; ) {
                // 使用transferTo方法传输剩余的字节,可能不会传输全部剩余字节,取决于操作系统的限制
                left -= from.transferTo((size - left), Math.min(left, Integer.MAX_VALUE), to);
            }
        } catch (IOException e) {
            // 捕获并处理可能发生的IOException
            e.printStackTrace();
        }
    }
}

统计文件个数

import java.io.IOException;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;

public class TestFilesWalkFileTree {
    public static void main(String[] args) throws IOException {
        AtomicInteger dirCount = new AtomicInteger();
        AtomicInteger fileCount = new AtomicInteger();
        
        // 遍历指定路径下的所有文件和目录
        Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91"), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                System.out.println("====> " + dir);
                dirCount.incrementAndGet(); // 增加目录计数
                return super.preVisitDirectory(dir, attrs);
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println(file);
                fileCount.incrementAndGet(); // 增加文件计数
                return super.visitFile(file, attrs);
            }
        });
        
        // 打印目录和文件的总数
        System.out.println("dir count: " + dirCount);
        System.out.println("file count: " + fileCount);
    }
}

统计文件和文件夹个数,的示例二

import java.io.IOException;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;

public class TestFilesWalkFileTree {
    public static void main(String[] args) throws IOException {
        AtomicInteger dirCount = new AtomicInteger();
        AtomicInteger fileCount = new AtomicInteger();
        
        // 遍历指定路径下的所有文件和目录
        Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91"), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                System.out.println("====> " + dir);
                dirCount.incrementAndGet(); // 增加目录计数
                return super.preVisitDirectory(dir, attrs);
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println(file);
                fileCount.incrementAndGet(); // 增加文件计数
                return super.visitFile(file, attrs);
            }
        });
        
        // 打印目录和文件的总数
        System.out.println("dir count: " + dirCount);
        System.out.println("file count: " + fileCount);
    }
}
统计文件个数

遍历子文件件和子文件夹

import java.io.IOException;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;

public class TestFilesWalkFileTree {
    public static void main(String[] args) throws IOException {
        // 创建两个AtomicInteger对象来跟踪目录和文件的数量
        AtomicInteger dirCount = new AtomicInteger();
        AtomicInteger fileCount = new AtomicInteger();
        
        // 使用Files.walkFileTree方法遍历指定路径下的所有文件和目录
        Files.walkFileTree(
            Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91"), // 指定要遍历的路径
            new SimpleFileVisitor<Path>() { // 提供一个自定义的SimpleFileVisitor来处理遍历过程中的每个文件和目录
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    System.out.println("====> " + dir); // 打印当前遍历到的目录
                    dirCount.incrementAndGet(); // 增加目录计数
                    return super.preVisitDirectory(dir, attrs); // 继续遍历
                }

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    System.out.println(file); // 打印当前遍历到的文件
                    fileCount.incrementAndGet(); // 增加文件计数
                    return super.visitFile(file, attrs); // 继续遍历
                }
            }
        );
        
        // 打印目录和文件的总数
        System.out.println("dir count: " + dirCount);
        System.out.println("file count: " + fileCount);
    }
}

查找文件夹下面的jar 文件

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;

public class TestFilesWalkFileTree {
    public static void main(String[] args) throws IOException {
        AtomicInteger jarCount = new AtomicInteger();
        Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91"), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                if (file.toString().endsWith(".jar")) {
                    System.out.println(file);
                    jarCount.incrementAndGet();
                }
                return super.visitFile(file, attrs);
            }
        });
        System.out.println("Jar count: " + jarCount);
    }
}

删除文件

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class TestFilesWalkFileTree {
    public static void main(String[] args) throws IOException {
        // 删除指定文件
        try {
            Files.delete(Paths.get("D:\\Snipaste-1.16.2-x64-副本"));
        } catch (NoSuchFileException e) {
            System.err.println("文件不存在: " + e.getFile());
        }

        // 遍历指定路径下的所有文件,并删除它们
        Files.walkFileTree(Paths.get("O:\\snipaste-1.16.2-x64-副本"), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println(file); // 打印文件路径
                Files.delete(file); // 删除文件
                return super.visitFile(file, attrs);
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                System.out.println("<==== 退出 " + dir); // 打印目录路径
                Files.delete(dir); // 删除目录
                return super.postVisitDirectory(dir, exc);
            }
        });
    }
}

复制文件夹,下所有文件,和文件夹

import java.io.IOException;
import java.nio.file.*;

public class TestFilesCopy {
    public static void main(String[] args) {
        String source = "C:\\Snipaste-1.16.2-x64";
        String target = "C:\\Snipaste-1.16.2-x64aaa";

        Files.walk(Paths.get(source)).forEach(path -> {
            try {
                String targetName = path.toString().replace(source, target);

                // 如果是目录
                if (Files.isDirectory(path)) {
                    Files.createDirectory(Paths.get(targetName));
                }
                // 如果是普通文件
                else if (Files.isRegularFile(path)) {
                    Files.copy(path, Paths.get(targetName));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}

 

标签:文件,java,NIO,buffer,读写,file,import,ByteBuffer,public
From: https://www.cnblogs.com/ZzwWan/p/18253024

相关文章

  • 实验7 文件应用编程
    task4.c1#include<stdio.h>2intmain()3{4FILE*fp;5charch;6intcount=0;7fp=fopen("data4.txt","r");8if(fp==NULL)9{10printf("failtoopenfile\n");11......
  • 【JavaWeb】文件上传
    前端代码<formaction="/upload"method="post"enctype="multipart/form-data"> 姓名:<inputtype="text"name="username"><br>年龄:<inputtype="text"name="age"><b......
  • dwm 文件上传/打开文件夹 白屏
    问题描述及解决我的chromium和code-oss在上传文件/打开文件夹时会出现白屏的情况,即打开文件管理器时发生。因为firefox没有出现这种情况,最先以为是chromium的bug,起先以为缺少包,遂安装gtk3,gtk4,qt5-base,qt6-base,然而问题没有解决,设置默认的文件管理器也无作用。后面发现是缩......
  • maven 加载不到 mybatis xml 配置文件
     <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin>......
  • 部署、安装和测试minio
    部署MinIO在server01部署MinIO,安装方式采用rpm离线安装,具体步骤可参考官方文档。获取MinIO安装包下载地址如下:https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20230809233022.0.0.x86_64.rpm,通过以下命令可直接将安装包下载至服务器wgethttps://dl.min......
  • linux在文件夹中查找文件内容
    linux在文件夹中查找文件内容在Linux中,可以通过以下多个途径,在文件夹中查找文件内容:1、使用grep命令:grep-r"要查找的内容"/path/to/folder-r参数表示递归地在文件夹及其子文件夹中搜索。/path/to/folder是要搜索的文件夹路径。2、使用ack命令ack"要查找的内容......
  • 知识库的创建(1) - KnowledgeFile文件加载和分割
    文章目录前言一、类的初始化方法`__init__`1.参数解析2.初始化步骤二、方法`file2docs`1.功能2.参数3.步骤三、方法`docs2texts`1.功能2.参数3.步骤四、方法`file2text`1.功能2.参数3.步骤五、方法`file_exist`1.功能2.返回3.方法`get_mtim......
  • Docker+Jenkins+Pipline实现SpringBoot项目input选择不同差异性yml文件打包、执行sh打
    场景Docker+Jenkins+Pipline如何获取git插件环境变量(提交sha、分支等)以及Jenkinsfile中获取sh执行结果(获取git最近提交信息):https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/139697004在上面的基础上实现了使用Jenkinsfile文件获取git的提交记录以及获取sh的执......
  • 11、docker-dockerfile--构建docker的镜像文件和容器的挂载卷方法 方式二挂载
    挂载方式二:此方式是在生成镜像的同时也实现挂载1、现在本机创建一个目录文件存放脚本·mkdir/home/docker-volume-test2、创建脚本文件·vim  /home/docker-volume-test/dockerfile01·内容如下:FROMcentos//表示......
  • Windows11系统Win32_EncryptableVolume.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个Win32_EncryptableVolume.dll文件(挑选合适......