Netty--文件编程
3. 文件编程
3.1 FileChannel
⚠️ FileChannel 工作模式
FileChannel 只能工作在阻塞模式下
获取
不能直接打开 FileChannel,必须通过 FileInputStream、FileOutputStream 或者 RandomAccessFile 来获取 FileChannel,它们都有 getChannel 方法
- 通过 FileInputStream 获取的 channel 只能读
- 通过 FileOutputStream 获取的 channel 只能写
- 通过 RandomAccessFile 是否能读写根据构造 RandomAccessFile 时的读写模式决定
读取
会从 channel 读取数据填充 ByteBuffer,返回值表示读到了多少字节,-1 表示到达了文件的末尾
int readBytes = channel.read(buffer);
写入
写入的正确姿势如下, SocketChannel
ByteBuffer buffer = ...;
buffer.put(...); // 存入数据
buffer.flip(); // 切换读模式while(buffer.hasRemaining()) {channel.write(buffer);
}
在 while 中调用 channel.write 是因为 write 方法并不能保证一次将 buffer 中的内容全部写入 channel
关闭
channel 必须关闭,不过调用了 FileInputStream、FileOutputStream 或者 RandomAccessFile 的 close 方法会间接地调用 channel 的 close 方法
位置
获取当前位置
long pos = channel.position();
设置当前位置
long newPos = ...;
channel.position(newPos);
设置当前位置时,如果设置为文件的末尾
- 这时读取会返回 -1
- 这时写入,会追加内容,但要注意如果 position 超过了文件末尾,再写入时在新内容和原末尾之间会有空洞(00)
大小
使用 size 方法获取文件的大小
强制写入
操作系统出于性能的考虑,会将数据缓存,不是立刻写入磁盘。可以调用 force(true) 方法将文件内容和元数据(文件的权限等信息)立刻写入磁盘
3.2 两个 Channel 传输数据
String FROM = "helloword/data.txt";
String TO = "helloword/to.txt";
long start = System.nanoTime();
try (FileChannel from = new FileInputStream(FROM).getChannel();FileChannel to = new FileOutputStream(TO).getChannel();) {from.transferTo(0, from.size(), to);
} catch (IOException e) {e.printStackTrace();
}
long end = System.nanoTime();
System.out.println("transferTo 用时:" + (end - start) / 1000_000.0);
输出
transferTo 用时:8.2011
超过 2g 大小的文件传输
public class TestFileChannelTransferTo {public static void main(String[] args) {try (FileChannel from = new FileInputStream("data.txt").getChannel();FileChannel to = new FileOutputStream("to.txt").getChannel();) {// 效率高,底层会利用操作系统的零拷贝进行优化, 2g 数据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();}}
}
实际传输一个超大文件
position:0 left:7769948160
position:2147483647 left:5622464513
position:4294967294 left:3474980866
position:6442450941 left:1327497219
3.3 Path
jdk7 引入了 Path 和 Paths 类
- Path 用来表示文件路径
- Paths 是工具类,用来获取 Path 实例
Path source = Paths.get("1.txt"); // 相对路径 使用 user.dir 环境变量来定位 1.txtPath source = Paths.get("d:\\1.txt"); // 绝对路径 代表了 d:\1.txtPath source = Paths.get("d:/1.txt"); // 绝对路径 同样代表了 d:\1.txtPath projects = Paths.get("d:\\data", "projects"); // 代表了 d:\data\projects
.
代表了当前路径..
代表了上一级路径
例如目录结构如下
d:|- data|- projects|- a|- b
代码
Path path = Paths.get("d:\\data\\projects\\a\\..\\b");
System.out.println(path);
System.out.println(path.normalize()); // 正常化路径
会输出
d:\data\projects\a\..\b
d:\data\projects\b
3.4 Files
检查文件是否存在
Path path = Paths.get("helloword/data.txt");
System.out.println(Files.exists(path));
创建一级目录
Path path = Paths.get("helloword/d1");
Files.createDirectory(path);
- 如果目录已存在,会抛异常 FileAlreadyExistsException
- 不能一次创建多级目录,否则会抛异常 NoSuchFileException
创建多级目录用
Path path = Paths.get("helloword/d1/d2");
Files.createDirectories(path);
拷贝文件
Path source = Paths.get("helloword/data.txt");
Path target = Paths.get("helloword/target.txt");Files.copy(source, target);
- 如果文件已存在,会抛异常 FileAlreadyExistsException
如果希望用 source 覆盖掉 target,需要用 StandardCopyOption 来控制
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
移动文件
Path source = Paths.get("helloword/data.txt");
Path target = Paths.get("helloword/data.txt");Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
- StandardCopyOption.ATOMIC_MOVE 保证文件移动的原子性
删除文件
Path target = Paths.get("helloword/target.txt");Files.delete(target);
- 如果文件不存在,会抛异常 NoSuchFileException
删除目录
Path target = Paths.get("helloword/d1");Files.delete(target);
- 如果目录还有内容,会抛异常 DirectoryNotEmptyException
遍历目录文件
public static void main(String[] args) throws IOException {Path path = Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91");AtomicInteger dirCount = new AtomicInteger();//文件夹原子计数器,线程安全AtomicInteger fileCount = new AtomicInteger();//文件原子计数器,线程安全Files.walkFileTree(path, new SimpleFileVisitor<Path>(){@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {System.out.println(dir);dirCount.incrementAndGet();//遍历到文件夹时增加计数return super.preVisitDirectory(dir, attrs);}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {System.out.println(file);fileCount.incrementAndGet();//遍历到文件时增加计数return super.visitFile(file, attrs);}});System.out.println(dirCount); // 133System.out.println(fileCount); // 1479
}
统计 jar 的数目
Path path = Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91");
AtomicInteger fileCount = new AtomicInteger();
Files.walkFileTree(path, new SimpleFileVisitor<Path>(){@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {if (file.toFile().getName().endsWith(".jar")) {//file.toString().endsWith(".jar")fileCount.incrementAndGet();}return super.visitFile(file, attrs);}
});
System.out.println(fileCount); // 724
删除多级目录
Path path = Paths.get("d:\\a");
Files.walkFileTree(path, new SimpleFileVisitor<Path>(){@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.delete(file);return super.visitFile(file, attrs);}@Overridepublic FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {Files.delete(dir);return super.postVisitDirectory(dir, exc);}
});
⚠️ 删除很危险
删除是危险操作,确保要递归删除的文件夹没有重要内容
拷贝多级目录
long start = System.currentTimeMillis();
String source = "D:\\Snipaste-1.16.2-x64";
String target = "D:\\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();}
});
long end = System.currentTimeMillis();
System.out.println(end - start);
相关文章:
Netty--文件编程
3. 文件编程 3.1 FileChannel ⚠️ FileChannel 工作模式 FileChannel 只能工作在阻塞模式下 获取 不能直接打开 FileChannel,必须通过 FileInputStream、FileOutputStream 或者 RandomAccessFile 来获取 FileChannel,它们都有 getChannel 方法 通过…...
SVN 服务器建立
1.建立SVN库 svnadmin create cat svndir/conf/passwd 修改SVN用户密码 chenht 123456 2.建立目录权限 [aliases] # joe /CXZ/STDessert/LSnake City/OSnake Oil, Ltd./OUResearch Institute/CNJoe Average [groups] # harry_and_sally harry,sally # harry_sally_…...

iPhone或在2024开放第三方应用商店。
iPhone或开放第三方应用商店,可以说这是一个老生常谈的话题。对于像是iOS这样封闭的系统来说,此前传出苹果可能开放侧载消息的时候,又有谁能信,谁会信? 如果是按照苹果自身的意愿,这种事情自然是不可能发生…...
《C和指针》笔记36:动态内存分配
1. malloc和free C函数库提供了两个函数,malloc和free,分别用于执行动态内存分配和释放。这些函数维护一个可用内存池。当一个程序另外需要一些内存时,它就调用malloc函数,malloc从内存池中提取一块合适的内存,并向该…...
C/S架构学习之基于UDP的本地通信(服务器)
基于UDP的本地通信(服务器):创建流程:一、创建数据报式套接字(socket函数): int sock_fd socket(AF_UNIX,SOCK_DGRAM,0);if(-1 sock_fd){perror("socket error");exit(-1);}二、创建…...

excel如何加密(excel加密的三种方法)
Excel是一款广泛使用的办公软件,有时候我们需要对一些重要的Excel文件进行加密,以保证文件的安全性。下面将介绍3种常用的Excel加密方法。 方法一:通过路径文件-另存为-工具-常规选项-设置打开或修改权限密码(密码只可以使数字、字…...

玩了个锤子游戏小程序搭建流程:探索深度与逻辑的结合
随着移动互联网的普及,小程序已经成为了越来越多用户的选择。在这个背景下,玩了个锤子游戏小程序应运而生,它为用户提供了一个全新的游戏体验。那么,如何搭建这样一个小程序呢?本文将为大家详细介绍玩了个锤子游戏小程…...
召回率计算及影响因素
召回率是指在所有正样本中,被成功预测为正样本的样本数占比。在机器学习领域,召回率是评估模型预测性能的重要指标之一。在本文中,我们将从多个方面深入探讨召回率的概念和应用。 阈值越高,精准率越高,召回率越低&…...

在Qt中怎么由函数定义自动创建函数实现模板
2023年11月12日,周日凌晨...
【算法】算法题-20231112
算法题 一、459. 重复的子字符串二、414. 第三大的数三、520. 检测大写字母四、680. 验证回文串 II五、283. 移动零 一、459. 重复的子字符串 简单 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。 示例 1: 输入: s “abab” 输出: true…...
目标检测YOLO实战应用案例100讲-基于多目标追踪的交通场景异常检测(续)
目录 3.5特征融合网络改进:小目标检测层 3.5.1小目标检测层 3.6实验结果与讨论...

最新支付宝转卡码生成之转账源代码(隐藏部分卡号)
一、需要准备好自己的卡号、名称、以及对应的姓名 二、然后将自己的信息填入下面的代码中 三、然后将拼接好的代码,利用转码技术生产对应的二维码 四、这样一个跳转银行卡二维码的转账码就做好了 效果演示:如下 支付宝扫码、跳转码、转卡码、隐藏卡号…...

聊天机器人框架Rasa资源整理
Rasa是一个主流的构建对话机器人的开源框架,它的优点是几乎覆盖了对话系统的所有功能,并且每个模块都有很好的可扩展性。参考文献收集了一些Rasa相关的开源项目和优质文章。 一.Rasa介绍 1.Rasa本地安装 直接Rasa本地安装一个不好的地方就是容易把本地…...

魔搭社区LLM模型部署实践, 以ChatGLM3为例(一)
魔搭社区LLM模型部署实践, 以ChatGLM3为 例 本文以ChatGLM3-6B为例, 主要介绍在魔搭社区如何部署LLM, 主要包括如下内容: ● SwingDeploy - 云端部署, 实现零代码一键部署 ● 多端部署 - MAC个人笔记本,…...
25期代码随想录算法训练营第十四天 | 二叉树 | 层序遍历(10道题)、226.翻转二叉树 、101.对称二叉树 2
目录 层序遍历 10226.翻转二叉树101.对称二叉树 2 层序遍历 10 链接 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right clas…...
ubuntu cp210x(USB转串口)驱动安装教程
ubuntu cp210x(USB转串口)驱动安装 前言1. 驱动下载2. 驱动编译和安装3. 可能遇到的问题及解决办法3.1 第一种解决方案:检查当前是否已有CP210x.ko驱动3.2 第二种解决方案:修改驱动文件,编译 前言 CP2108 是一款高度集…...
Spring-SpringAOP的实现
对Spring AOP的理解 OOP表示面向对象编程,是一种编程思想,AOP表示面向切面编程,也是一种编程思想 Spring AOP:Spring为了让程序员更加方便的做到面向切面编程所提供的技术支持 Spring提供的一套机制,让我们更容易的…...
js:Browserslist用特定语句查询浏览器列表的工具与Babel和Postcss配置使用
目录 BrowserslistBabel 和 BrowserslistPostcss 和 Browserslist推荐配置参考文章 Browserslist Browserslist 是一个用特定语句查询浏览器列表的工具 文档 https://www.npmjs.com/package/browserslisthttps://github.com/browserslist/browserslist#full-list 安装 pnp…...
odoo16前端框架源码阅读——boot.js
odoo16前端框架源码阅读——boot.js 从名字就能看出来,这个文件是一个启动文件。 odoo前端将所有的js打包成了两个文件,一个是common.js,另一个是backend.js, 而common.js 是最先加载的 在common.js打包的js文件中最先加载的是下面的文件,看…...

使用MybatisPlus时出现的java.lang.NullPointerException异常~
错误描述如下所示: 错误原因:Junit的导包错误 单元测试的包有如下所示两个 我们应该根据springboot的版本进行选择, 在Spring Boot 2.2.X以后使用import org.junit.jupiter.api.Test Junit5 在Spring Boot 2.2.x之前使用import org.junit.T…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...