当前位置: 首页 > news >正文

备案 手机网站微信小程序怎么收费

备案 手机网站,微信小程序怎么收费,沪佳装修贵吗,网站服务器的重要性这里是小奏,觉得文章不错可以关注公众号小奏技术 背景 java nio中文件读写不管是普通文件读写,还是基于mmap实现零拷贝,都离不开FileChannel这个类。 随便打开RocketMQ 源码搜索FileChannel 就可以看到使用频率 kafka也是 所以在java中文件读写FileCh…

这里是小奏,觉得文章不错可以关注公众号小奏技术

背景

java nio中文件读写不管是普通文件读写,还是基于mmap实现零拷贝,都离不开FileChannel这个类。

随便打开RocketMQ 源码搜索FileChannel

就可以看到使用频率

kafka也是

所以在java中文件读写FileChannel尤为重用

java文件读写全流程

这里说的仅仅是FileChannel基于堆内存(HeapByteBuffer)的文件读写。

如果是mmap或者堆外内存,可能有些步骤会省略,相当于有一些优化

  1. FileChannel调用read,将HeapByteBuffer拷贝到DirectByteBuffer
  2. JVM在native层使用read系统调用进行文件读取, 这里需要进行上下文切换,从用户态进入内核态
  3. JVM 进程进入虚拟文件系统层,查看文件数据再page cache是否缓存,如果有则直接从page cache读取并返回到DirectByteBuffer
  4. 如果请求文件数据不在page caceh,则进入文件系统。通过块驱动设备进行真正的IO,并进行文件预读,比如读取的文件可能只有1-10,但是会将1-20都读取
  5. 磁盘控制器DMA将磁盘中的数据拷贝到page cache中。这里发生了一次数据拷贝(非CPU拷贝)
  6. CPU将page cache数据拷贝到DirectByteBuffer,因为page cache属于内核空间,JVM进程无法直接寻址。这里是发生第二次数据拷贝
  7. JVM进程从内核态切换回用户态,这里如果使用的是堆内存(HeapByteBuffer),实际还需要将堆外内存DirectByteBuffer拷贝到堆内存(HeapByteBuffer)

FileChannel读写文件(非MMAP)

public static void main(String[] args) {String filename = "小奏技术.txt";String content = "Hello, 小奏技术.";// 写入文件writeFile(filename, content);// 读取文件System.out.println("Reading from file:");readFile(filename);}public static void writeFile(String filename, String content) {// 创建文件对象File file = new File(filename);// 确保文件存在if (!file.exists()) {try {boolean created = file.createNewFile();if (!created) {System.err.println("Unable to create file: " + filename);return;}} catch (Exception e) {System.err.println("An error occurred while creating the file: " + e.getMessage());return;}}// 使用FileChannel写入文件try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");FileChannel fileChannel = randomAccessFile.getChannel()) {ByteBuffer buffer = ByteBuffer.allocate(content.getBytes().length);buffer.put(content.getBytes());buffer.flip(); // 切换到读模式while (buffer.hasRemaining()) {fileChannel.write(buffer);}} catch (Exception e) {System.err.println("An error occurred while writing to the file: " + e.getMessage());}}public static void readFile(String filename) {// 使用FileChannel读取文件try (RandomAccessFile randomAccessFile = new RandomAccessFile(filename, "r");FileChannel fileChannel = randomAccessFile.getChannel()) {ByteBuffer buffer = ByteBuffer.allocate((int) fileChannel.size());while (fileChannel.read(buffer) > 0) {// Do nothing, just read}// 切换到读模式buffer.flip(); /* while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}*/Charset charset = StandardCharsets.UTF_8; String fileContent = charset.decode(buffer).toString();System.out.print(fileContent);} catch (Exception e) {System.err.println("An error occurred while reading the file: " + e.getMessage());}}

这里需要注意的一个细节
我们分配的内存的方式是

ByteBuffer.allocate()

这里我们可以进入看看源码

实际构造的是HeapByteBuffer,也就是JVM的堆内存

如果我们使用

ByteBuffer.allocateDirect()

则构造的是堆外内存DirectByteBuffer

HeapByteBuffer和DirectByteBuffer文件读写区别

我们看看FileChannel read方法

发现IO相关的处理被封装在IOUtil

我们继续看看IOUtilwrite方法

可以看到如果是DirectBuffer则可以直接写

如果是HeapByteBuffer则需要转换为DirectByteBuffer

为什么要在DirectByteBuffer做一层转换

主要是HeapByteBuffer受JVM管理,也就是会受到GC影响

如果在进行native调用的时候发生了GC,会导致HeapByteBuffer的内容出现错误

具体详细的说明可以看看这篇MappedByteBuffer VS FileChannel:从内核层面对比两者的性能差异

讲解的非常清晰

参考

  • MappedByteBuffer VS FileChannel:从内核层面对比两者的性能差异
http://www.yayakq.cn/news/417244/

相关文章:

  • 秦皇岛网站推广哪家好徐州网页设计培训
  • 企业网站建设的方式有哪些方式郑州做网站好的公
  • com网站是用什么做的锚文本外链网站
  • 做公司的网站的需求有哪些内容phpcmsv9手机网站源码
  • 网站验证网络营销模式的优势
  • 网站建设设计有哪些网站开发与设计培训
  • 科协网站页建设的意义站酷网官网入口
  • 网站 建设运行情况报告想要提高网站排名应该怎么做
  • 上海网页制作与网站设计免费动画制作软件
  • 网站建设长沙网站建设销售总结
  • 专业房产网站建设公司用系统建购物网站
  • 北京市保障房建设投资中心网站瘫痪招标网站建设方案
  • 购物网站开发语言欧美在线网站设计教程
  • 做100个网站效果苏州网站制作工作室
  • cnzz统计代码放在后台网站为什么没显示万能软文模板
  • 做薆视频网站免费商标设计logo
  • 阿里网站建设需要准备什么商务网站创建经费预算
  • 做网站赚广告08影院 wordpress 0.8
  • 高频网站开发大学网页设计期末作品
  • 手表网站推荐江门专业网站建设公司
  • 学校网站建设情况汇报网站建设服务中心
  • 网站色彩运用网页制作模板软件
  • 自贡市城市建设投资开发集团有限公司网站天津建设网站安全员考试成绩查询
  • 网站开发用的工具网站所有权
  • 沈阳seo建站网络安全工程师是干嘛的
  • 网络广告推广网站中山专业外贸网站开发
  • 手机网站建设外包js做网站登录
  • 招聘网站数据分析要怎么做赣州室内设计学校
  • 怎么做彩票网站代理兰州网站制作培训班
  • 建设项目查询官网兰州网站建设与优化推广