以下的例程提供了一个快速缓冲的文件 I/O 系统, 它支持基于 Haruhiko Okumura 写的 LZSS 压缩器使用一个环状缓冲互除法 来支持读写压缩文件. 这没有实现象 zip 和 lha 程序那样好的压缩率, 但解压缩非常的快而且不需要很多内存. 压缩文件总是由一个 32 位的值 F_PACK_MAGIC 开始, 自动用值 F_NOPACK_MAGIC 检测文件.
char *fix_filename_case(char *path);
转换文件名到基本大小写设置. DOS 下,
将是全部大写. 返回一个路径参数的拷贝.
char *fix_filename_slashes(char *path);
转换所有的目录分割符.
在 DOS 下, 转换成反斜杠. 返回路径参数的拷贝.
char *fix_filename_path(char *dest, char *path, int size);
转换部分文件名到完全路径名, 长度限制在指定的字符个数.
返回 dest 参数的拷贝.
char *replace_filename(char *dest, char *path, char *filename, int size);
替换指定的路径+文件名为新的文件名,
长度限制在指定的最大字符个数.返回 dest 参数的拷贝.
char *replace_extension(char *dest, char *filename, char *ext, int size);
替换指定文件名+后缀为新的后缀,
长度限制在指定的最大字符个数.
返回 dest 参数的拷贝.
char *append_filename(char *dest, char *path, char *filename, int size);
连接指定的文件名到指定路径的末尾,
长度限制在指定的最大字符个数.
返回 dest 参数的拷贝.
char *get_filename(char *path);
当传入一个完整的指定文件路径, 这个返回指向文件名的指针.
'\' 和 '/' 都将被看作是目录分隔符.
char *get_extension(char *filename);
当传入一个完整的文件名 (有或没有路径信息)
这返回指向文件扩展名的指针.
void put_backslash(char *filename);
如果文件名的最后字符不是 '\', '/', 或 '#',
这个例程将接上一个 '\' 在上面.
int file_exists(char *filename, int attrib, int *aret);
检查匹配给出的名字和属性的文件是否存在,
如果是返回非零. 文件属性可能包含有 dir.h 里定义的 FA_* 中任何一个.
如果 aret 不是 NULL, 它将被设置成匹配文件的属性.
如果错误发生, 系统错误代码将被储存在 errno 中.
int exists(char *filename);
file_exists() 的快捷方式版本, 它检查正常的文件,
就是文档型或者设置了只读属性位的, 但是不检查隐含文件,
目录, 系统文件, 等等.
long file_size(char *filename);
以字节为单位返回文件长度. 如果文件不存在或错误发生了,
它将返回零并将系统出错码放在 errno 里.
long file_time(char *filename);
返回文件的更改时间.
int delete_file(char *filename);
从磁盘中删除一个文件.
int for_each_file(char *name, int attrib, void (*callback)(), int param);
在磁盘上寻找匹配给定的统配符和文件属性的文件,
没找到一个就执行一次 callback().
callback() 将被传入三个参数, 第一个字符串包含了完整的文件名,
第二个为文件的属性,
第三个是一个整数它就是 param 简单的复制 (你可以按你自己的任何想法来使用它).
如果发生了错误, 错误码将储存在 errno 里,
callback() 可以由自己设置 errno 来导致 for_each_file() 退出.
返回成功调用 callback() 的次数.
文件属性可以包含 dir.h 里的 FA_* 标志中的任何一个.
void packfile_password(char *password);
设置密码口令用来使用压缩文件的所有读写操作.
文件经过设置障碍口令写入后如果不设置同样的口令将不能读,
因此小心点: 如果你忘掉了密码,
我不能恢复你的数据! 传入 NULL 或一个空串将返回到正常,
无障碍模式.
如果你使用这个函数来阻止人们得到你的数据文件的控制权,
注意不要在你的可执行文件中储存明显的口令:
如果有任何字符串象 "I'm the password for the datafile",
那么得到你的数据的控制权就相当的简单 :-)
PACKFILE *pack_fopen(char *filename, char *mode);
以某个模式打开一个文件, 模式可以包含以下标志:
压缩文件函数也能理解一些 "magic" 文件名用作特殊的效果.
就是:
这所有的都和 stdio 函数工作相同,
除了 pack_fread() 和 pack_fwrite() 只需要单个的 size 参数以取代
愚蠢的 size 和 num_elements 方式, 而且定位仅支持相对当前位置的前移运动.
pack_fgets() 函数没有在返回字符串里包含结果.
pack_i* 和 pack_m* 例程分别使用 Intel
和 Motorola 字节次序系统 (endianness) 读写 16 和 32 位值.
注意当读取压缩文件时定位操作非常的慢,
因此当你不能确认文件是没有压缩的时应尽量避免这个操作.
读取快, 使用代码:
PACKFILE *pack_fclose_chunk(PACKFILE *f);
int pack_fclose(PACKFILE *f);
int pack_fseek(PACKFILE *f, int offset);
int pack_feof(PACKFILE *f);
int pack_ferror(PACKFILE *f);
int pack_getc(PACKFILE *f);
int pack_putc(int c, PACKFILE *f);
int pack_igetw(PACKFILE *f);
long pack_igetl(PACKFILE *f);
int pack_iputw(int w, PACKFILE *f);
int pack_igetw(PACKFILE *f);
long pack_igetl(PACKFILE *f);
int pack_iputw(int w, PACKFILE *f);
long pack_iputl(long l, PACKFILE *f);
int pack_mgetw(PACKFILE *f);
long pack_mgetl(PACKFILE *f);
int pack_mputw(int w, PACKFILE *f);
long pack_mputl(long l, PACKFILE *f);
long pack_fread(void *p, long n, PACKFILE *f);
long pack_fwrite(void *p, long n, PACKFILE *f);
char *pack_fgets(char *p, int max, PACKFILE *f);
int pack_fputs(char *p, PACKFILE *f);
PACKFILE *pack_fopen_chunk(PACKFILE *f, int pack);
打开文件的子块, 块主要是为数据文件使用而设计,
但是它们也可以用在你自己的文件例程中.
一个块提供的文件的一部分的逻辑形式,
它可以作为一个独立实体压缩并将自动插入,检查长度记数可以阻止读到块外去.
使用下面的代码写块到文件 f:
/* 假定 f 是一个 PACKFILE * 它以写模式打开 */
f = pack_fopen_chunk(f, pack);
write some data to f
f = pack_fclose_chunk(f);
写入块的数据将由两个长度记数预处理 (32 位, big-endian).
对不压缩的块这两个将被设置为块中数据的大小.
对压缩的块 (设置了 pack 标志而创建的),
第一个长度将设为实际的块长度,
第二个将设为压缩前的数据长度的负值.
/* 假定 f 是一个 PACKFILE * 它被以读模式打开 */
f = pack_fopen_chunk(f, FALSE);
read data from f
f = pack_fclose_chunk(f);
顺序是先读块建立时的长度记数,
如果它被压缩了就自动解压缩.
长度也是用来阻止读到块以外
(如果你试图干这个, Allegro 将返回 EOF),
当你调用 pack_fclose_chunk() 时自动的忽略掉任何没有读的块数据.
块可以被重复调用 pack_fopen_chunk() 来递归处理.
当写向一个文件, 压缩状态将从父文件继承,
因此你仅仅只需在父文件没压缩但你想压缩块数据时才需要设置 pack 标志.
如果父文件已经由压缩模式打开了,
设置 pack 标志将使数据压缩两次:
一次是写向块,
又一次是在块传到父文件后.
关闭前面由调用 pack_fopen_chunk() 打开的文件中的子块.