首页 > 编程语言 >Java IO主动同步数据到磁盘方式

Java IO主动同步数据到磁盘方式

时间:2023-07-05 22:11:36浏览次数:35  
标签:FileChannel force IO write Java FileOutputStream file new 磁盘

前言

通过输出流的write方法可能只是会写到操作系统的缓冲区(page cache)中,再由操作系统在合适的时机将缓冲区的数据同步到磁盘中。Linux提供了两个函数fsync()、fdatasync()来强制让操作系统将数据同步到磁盘,它们的区别是是否需要同步文件的元数据,如果访问时间,修改时间,文件大小等信息,而fdatasync()不会同步文件的元数据。

Java主动同步数据的API

  • FileDescriptor.sync()
  • FileChannel.force()或者MappedByteBuffer.force()
  • 使用RandomAccessFilerws或者rwd模式打开文件

FileDescriptor.sync()

在创建FileOutputStream输出流,会自动创建FileDescriptor对象,我们可以通过getFD方法拿到FileDescriptor对象。

public FileOutputStream(File file, boolean append) throws FileNotFoundException
{
    String name = (file != null ? file.getPath() : null);
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkWrite(name);
    }
    if (name == null) {
        throw new NullPointerException();
    }
    if (file.isInvalid()) {
        throw new FileNotFoundException("Invalid file path");
    }
    this.fd = new FileDescriptor();
    fd.attach(this);
    this.append = append;
    this.path = name;

    open(name, append);
}
try (FileOutputStream fos = new FileOutputStream("in.txt")) {  
    // write something
    fos.getFD().sync();  
}

sync方法是一个native方法,底层调用了fsync

FileChannel.force()或者MappedByteBuffer.force()

通过nio中的FileChannel的force方法同步,其中force(true)相当于fsyncforce(false)相当于fdatasync。也就是说force(true)会同步元数据。

通过FileChannel.map()方法拿到的MappedByteBuffer原理一样。

try (FileOutputStream fos = new FileOutputStream("in.txt")) {  
    // write something
    // sync
    fos.getChannel().force(true);  
}

// 直接使用FileChannel
try (FileChannel channel = FileChannel.open(Paths.get("hello.txt"), StandardOpenOption.CREATE,tandardOpenOption.WRITE)) {
    // write something
    // sync
    channel.force(true);
}

RandomAccessFile以rws或者rwd模式打开文件

// 等于force(true), fsync
RandomAccessFile file = new RandomAccessFile("hello.txt", "rws"));
// 等于force(false), fdatasync
RandomAccessFile file = new RandomAccessFile("hello.txt", "rwd"));

OutputStream.flush

flush方法只是将缓存在堆内存的数据通过输出流的write方法写入,并不保证操作系统将数据同步到磁盘中,这点可以看注释文档。

比如常见的BufferedOutputStream,我们在写入方法后都要调用flush方法(close方法也会自动调用flush)。来看看它的实现

public synchronized void flush() throws IOException {
    // 刷新缓冲区
    flushBuffer();
    out.flush();
}

/**
 * 如果有数据, 将java堆内存的字节数组通过实际的输出流写出(也就是写入到操作系统)
 */
private void flushBuffer() throws IOException {
    if (count > 0) {
        // out通常是FileOutputStream,通过构造方法传入, 当然也可以是别的输出流
        out.write(buf, 0, count);
        count = 0;
    }
}

/**
 * BufferedOutputStream写入操作
 * 实际是往缓冲区字节数组追加元素,如果发现数据长度已经大于缓冲区字节数组长度时,就把数据刷到
 * 操作系统
 */
public synchronized void write(int b) throws IOException {
    if (count >= buf.length) {
        flushBuffer();
    }
    buf[count++] = (byte)b;
}

标签:FileChannel,force,IO,write,Java,FileOutputStream,file,new,磁盘
From: https://www.cnblogs.com/wt20/p/17530115.html

相关文章

  • 阿里Java二面:说说Spring MVC执行流程及原理?这样聊能吊打面试官
    面试找虐博主之前每次去面试必问的问题:“讲一下springmvc的执行流程以及常用组件的作用”;记得第一次和面试官说了大概的流程是这样的:“服务器收到一个请求后会先去HandlerMapping中匹配url,找到url之后用HandlerAdapter适配器去执行这个控制器(controller层),执行完之后返回一个mo......
  • 阿里Java二面:说说Spring MVC执行流程及原理?这样聊能吊打面试官
    面试找虐博主之前每次去面试必问的问题:“讲一下springmvc的执行流程以及常用组件的作用”;记得第一次和面试官说了大概的流程是这样的:“服务器收到一个请求后会先去HandlerMapping中匹配url,找到url之后用HandlerAdapter适配器去执行这个控制器(controller层),执行完之后返回一个mode......
  • Java 方法的重载、可变参数、作用域
    Java方法的重载、可变参数、作用域1.方法的重载使用相同的方法名来定义不同的方法,方法的重载能优化代码,减少冗余度。在使用方法的重载需要注意的地方有:1.方法的重载需要方法名相同,并且形参类别、个数、顺序不同(满足其中之一)2.方法的重载与方法的返回类型、形参名没有关......
  • 从头学Java17-Stream API(二)结合Record、Optional
    StreamAPIStreamAPI是按照map/filter/reduce方法处理内存中数据的最佳工具。本系列教程由Record讲起,然后结合Optional,讨论collector的设计。使用Record对不可变数据进行建模Java语言为您提供了几种创建不可变类的方法。可能最直接的是创建一个包含final字段的final类。......
  • Illegal mix of collations
    原因:创建表的时候未设置COLLATE临时解决:CONVERT(rr.operator_idUSINGutf8)COLLATEutf8_unicode_ci=CONVERT(pw.idUSINGutf8)COLLATEutf8_unicode_ci参考:https://blog.csdn.net/weixin_43543654/article/details/128862974......
  • IOI 2015 Teams 分组
    IOI2015Teams分组题意班里有\(N\)个学生,他们的编号为从\(0\)到\(N-1\)。每天,老师都有一些项目需要学生去完成。每个项目都需要由一组学生在一天内完成。项目的难度可能不同。对于每个项目,老师知道应该选择由多少学生组成的小组去完成。不同的学生对小组的规模有不同的......
  • cookie和session区别
    什么是Session?服务器会给每个用户创建一个Session对象,用来存储特定用户会话所需要的属性及配置信息。session代表的是一次对话,当浏览器第一次访问服务器时,服务会创建一个session对象,它携带着用户的信息(如登录信息),用户可以在此网站下的所有web页跳转。当会话过期或被放弃,服务......
  • 关于IO技术的介绍
    什么是IO输入(Input)指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据)。输出(Output)指的是:程序输出数据给外部系统从而可以操作外部系统(核心含义是“写”,将数据写出到外部系统)。java.io包为我们提供了相关的API,实现了对所有外部系统的输入输出操作。什么是数据源......
  • JavaScript(七)ES6
    Node环境安装nvm、npm、nrmnvm:管理多个版本的node环境,使用nvm安装nodejsnpm:npm是node的包管理工具,使用nvm安装node后,就可以使用npm命令nrm:管理npm的镜像源,使用npm命令安装Babel转码器可以将es6代码转成es5代码。从而可以在老版本浏览器执行在项目根目录下安装np......
  • mybatis association 的用法(完整版)
    packagecom.tuling.tulingmall.domain;importcom.tuling.tulingmall.model.UmsMember;importcom.tuling.tulingmall.model.UmsMemberLevel;importlombok.Data;@DatapublicclassPortalMemberInfoextendsUmsMember{privateUmsMemberLevelumsMemberLevel;......