前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >行百里者半九十,文件写90%崩了呢?

行百里者半九十,文件写90%崩了呢?

作者头像
Apache IoTDB
发布2020-09-27 10:40:44
5370
发布2020-09-27 10:40:44
举报
文章被收录于专栏:Apache IoTDB

上篇文章我们介绍了第一个文件格式:

什么是文件格式?

在这里没有对文件有任何的异常处理。假如文件写坏了怎么办?如果一个文件很大,比如你在下片,好几个G,下到一半网断了,是不是很崩溃?这时候就需要断点续传。本文介绍一种文件的断点恢复方法:实现Undo日志。

文件的恢复其实是一种 undo 日志。将文件的内容分成一个一个,每一个可以看成是一个事务,当事务完成时记录检查点。在数据库中,假如一个事务做了一半系统挂掉,可以根据 undo 日志将数据项设置为旧值。类似微信的撤销消息(因为要记录日志,为了减少空间占用,所以微信将其限制在了2分钟,我猜的)。

写文件的 undo 日志很容易实现,记录每个完整小块的结尾位置。一旦出现错误,直接将最新检查点位置后边的不完整数据删掉。java 中一般用 truncate 方法截断文件。

举个例子,每个由 4 个字节组成,每写完 1 个块,就在另一个文件中记录一个当前文件的最新位置。比如写了5个块,共 20 个字节,检查点记录了五个:4,8,12,16,20。这时候又写了 2 个字节,崩了。

为了继续写文件,需要根据检查点的 20,将文件从 20 处截断。

java nio FileChannel 的 truncate 可以干这个事,RandomAccessFile 和 FileOutputStream 都可以获得当前 FileChannel。

此外,RandomAccessFile 还可以直接用 setLength()。他们都接收一个 long 类型的文件长度,这个位置之后的内容都会被丢弃。

那么截断后怎么继续写呢?一种很简单的方式是使用 append 模式开一个 FileOutputStream,继续在文件末尾写数据就好了。

总结

今天介绍了一种文件的错误恢复方式,这种方式依赖一个日志文件,这个日志文件也可以换成一个数据库。记检查点的频率会影响写文件的效率,也会影响错误恢复时丢失的数据量,需要自己平衡。

之前我们有讨论过 RandomAccessFile 可以直接定位到文件的某个位置写新的数据,看起来也可以进行断点恢复,但是需要保证新写的数据比需要截断的数据长。

代码:

https://github.com/qiaojialin/Java-IO-Learning

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Apache IoTDB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档