文档格式
什么是文件格式
wiki 定义:
A file format is a standard way that information is encoded for storage in a computer file. It specifies how bits are used to encode information in a digital storage medium.
翻译一下:
文件格式是将信息进行编码并存储在计算机文件中的标准方式。它指定如何使用字节来编码信息,并存储在数字存储媒介中。
人话:
就是告诉你数据是怎么存在文件中的。有了文件格式,你就可以将数据写成这种格式的文件,并且将数据从这种格式的文件中读出来。文件格式的本质就是一种协议。
举个例子,word、excel、PPT 就是文件格式,他们按照自己的格式进行组织,计算机中不同的文件后缀就代表不同格式的文件,同样格式的文件的内容可以不同。
开发一种文件格式,一般都需要开发读写接口。最简单的写接口是将一个数据写入到文件中,最简单的读接口就是把里边的所有数据全部读出来(这里的读出来,一般需要以用户可认识的格式读出来。不能用户写了个a,你读出来个#,然后跟用户说 # 就是 a ,这是耍流氓)。
再举例子,word 给人提供了一个界面,让你可以写文字。保存关闭之后再打开。他还能给你展示之前写入的内容,这就是读文件。
文件格式一般包含两部分:data 和 metadata。data 即数据;metadata 即元数据(描述数据的数据),比如这个文件中一共有几条数据,数据的起始位置是多少,长度是多少。
下面介绍一个自己的文件格式:
自己的文件格式
这个文件格式的功能为:写 int 数据;读取所有数据。
文件结构如下图:因为文件在磁盘上是一维结构,因此文件格式就直接画成一条线了,这个文件格式中,前边是数据,最后是元数据。当然你也可以设计成其他样子,比如元数据和数据交叉存放。这里只介绍一个比较简单的。
原料如下:写流程用到了 ByteArrayoutputstream 和 FileOutputStream。 读流程用到了 RandomAccessFile。这里的 metadata 就是一个 int 类型的 count,记录文件中数据的个数。isWrite 用来判断此实例是读流程还是写流程。一般文件格式都是先写,关闭之后再另起线程进行读取。
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
public class MyFileFormat {
private RandomAccessFile raf;
private FileOutputStream out;
private ByteArrayOutputStream baos;
private File file;
private int count = 0;
private boolean isWrite;
// 初始化文件读写接口
public MyFileFormat(String pathStr, boolean isWrite) throws filenotfoundException {
Path path = Paths.get(pathStr);
file = path.toFile();
this.isWrite = isWrite;
if(isWrite) {
out = new FileOutputStream(file, false);
baos = new ByteArrayOutputStream();
} else {
raf = new RandomAccessFile(file, "r");
}
}
// 写一个 int
public boolean write(int value) {
try {
// 将数据缓存进 baos 中并计数
baos.write(Utils.intToBytes(value));
count++;
} catch (IOException e) {
e.printstacktrace();
return false;
}
return true;
}
// 写入 count 计数,即 metadata,最后关闭文件
public void close() throws IOException {
if(isWrite) {
baos.write(Utils.intToBytes(count));
baos.writeTo(out);
out.close();
} else {
raf.close();
}
}
// 先读 metadata,再读数据
public int[] read() throws IOException {
long offset = file.length() - 4;
raf.seek(offset);
byte[] bytes = new byte[4];
int result = raf.read(bytes);
count = Utils.bytesToInt(bytes);
if(result != bytes.length)
throw new IOException("not read enough bytes");
int[] ret = new int[count];
raf.seek(0);
for(int i = 0; i < count; i++) {
result = raf.read(bytes);
if(result != bytes.length)
throw new IOException("not read enough bytes");
int value = Utils.bytesToInt(bytes);
ret[i] = value;
}
return ret;
}
public static void main(String[] args) throws IOException {
// 写数据、关闭文件
MyFileFormat myfile = new MyFileFormat("test.myfile", true);
for(int i = 0; i < 20; i++) {
myfile.write(i);
}
myfile.close();
// 读数据、关闭文件
myfile = new MyFileFormat("test.myfile", false);
int[] ret = myfile.read();
myfile.close();
for(int a: ret){
System.out.print(a + " ");
}
}
}
class Utils {
public static byte[] intToBytes(int i) {
byte[] result = new byte[4];
result[0] = (byte) ((i >> 24) & 0xFF);
result[1] = (byte) ((i >> 16) & 0xFF);
result[2] = (byte) ((i >> 8) & 0xFF);
result[3] = (byte) (i & 0xFF);
return result;
}
public static int bytesToInt(byte[] bytes) {
int value = 0;
// high bit to low
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (bytes[i] & 0x000000FF) << shift;
}
return value;
}
}
读方法:先读文件末尾的 metadata,再读数据。上边我们说了,metadata 一般包括了数据的个数,所在位置,长度。但是这里的 metadata 只有一个数据的个数。这是不是有问题了?没问题,因为我们的数据都是 int,占 4 个字节,所以数据整体长度就有了。并且我们的数据是从 文件开头开始写的,因此所在位置也是预先知道的。 这就是文件格式,怎么写的怎么读。
另一个方面也不能忽略,那就是 metadata 其实也是一种数据,那么 metadata 我们是怎么读的呢?其实 metadata 也需要自己的 metadata,这样就无穷无尽无止境了,metadta 还有 metadata。。。但是,是有止境的,一般那个终止点再文件的开头或结尾,存储了一个位置相邻的 metadata 的长度。这样,就找到了第一个metadata。之后的就可以一连串找出来了。比如在这个例子中,这个终止点是一个 int,存在文件的末尾,占 4 个字节。
一般设计一款文件格式需要考虑以下几个事:
(1)data 和 metadtata 如何组织:放在一起还是分开,metadata有几层等。
(2)写入流程中内存占用:在内存缓存多少数据后刷到磁盘。
(3)如何降低磁盘占用:用什么压缩编码方式。
(4)如何加速查询:用什么索引,如何过滤。
(5)文件是否支持修改:是直接覆盖还是生成新文件。
代码:
https://github.com/qiaojialin/Java-IO-Learning
相关阅读
原文地址 http://blog.csdn.net/dinggo/archive/2007/12/29/2003425.aspx1. 概述现在很多智能手机都支持多媒体功能
一、概述MP4文件封装格式,对应的标准为ISO/IEC 14496-12,即信息技术 视听对象编码的第12部分:ISO 基本媒体文件格式(Information te
dBase是第一个在个人电脑上被广泛使用的单机版数据库系统,在CP/M与DOS的时期,由Ashton-Tate公司所发表。在1980年,它最初是出现在CP/
我今天做个教程教大家如何把自己喜欢的网页保存,保存成脱机文件这样在没网的时候也可以看到帖子的内容,很适合于保存技术贴或者图片
.概述Waveform Audio File Format(WAVE,又或者是因为WAV后缀而被大众所知的),它采用RIFF(Resource Interchange File Format)文件格式结