复制一个空洞文件且忽略掉其空洞内容
2014-11-21 11:17
204 查看
首先说一下什么叫做空洞文件!比如说,下面这段代码:
在这段代码中,我首先在文件中写入abcde五个字节的内容,然后在把文件指针从文件尾端向后移动5个字节,再写入ABCDE5个字节的内容!这样在这个文件中,两次abcde中间就会产生一个5个字节空洞,这个空洞的内容都被写成了0。文件的空洞并不要求在磁盘上占用存储区,具体的处理方式和文件系统的实现有关!我这个文件如果用vim打开的话会是这样的效果!
中间蓝色的^@就表示内容为0的空洞!
接下来,我们再来谈一谈如何来复制一个空洞文件,并且让忽略掉它的空洞部分的内容!这里我们就利用了空洞内容为0的这个特性!具体的实现方法就是通过查看读出来的文件内容的值是否为0,如果是则忽略,否则就存储起来!具体的实现代码如下:
上面那个程序的思路就是每次读取4096字节,分批读取源文件的内容到buf_r中,然后检查buf_r的内容,如果是0则忽略,否则就暂存到buf_w中,然后将其写入到目标文件中!
检验这个程序的运行结果我用了一个较大的空洞文件,具体的运行结果如下图:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<errno.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #define MODE O_CREAT|O_RDWR|O_TRUNC int main(int argc,char *argv[]) { int fd; if(argc != 2) { printf("Usage:%s <filename>\n",argv[0]); exit(EXIT_FAILURE); } if(-1 == (fd=open(argv[1],MODE,0644))) { printf("%s[open]%s\n",argv[0],strerror(errno)); exit(EXIT_FAILURE); } if(-1 == write(fd,"abcde",5)) { printf("%s[write]%s\n",argv[0],strerror(errno)); exit(EXIT_FAILURE); } if(-1 == lseek(fd,5,SEEK_END)) { printf("%s[lseek]%s\n",argv[0],strerror(errno)); exit(EXIT_FAILURE); } if(-1 == write(fd,"ABCDE",5)) { printf("%s[write]%s\n",argv[0],strerror(errno)); exit(EXIT_FAILURE); } if(-1 == close(fd)) { printf("%s[close]%s\n",argv[0],strerror(errno)); exit(EXIT_FAILURE); } printf("空洞文件已经创建成功!\n"); return 0; }
在这段代码中,我首先在文件中写入abcde五个字节的内容,然后在把文件指针从文件尾端向后移动5个字节,再写入ABCDE5个字节的内容!这样在这个文件中,两次abcde中间就会产生一个5个字节空洞,这个空洞的内容都被写成了0。文件的空洞并不要求在磁盘上占用存储区,具体的处理方式和文件系统的实现有关!我这个文件如果用vim打开的话会是这样的效果!
中间蓝色的^@就表示内容为0的空洞!
接下来,我们再来谈一谈如何来复制一个空洞文件,并且让忽略掉它的空洞部分的内容!这里我们就利用了空洞内容为0的这个特性!具体的实现方法就是通过查看读出来的文件内容的值是否为0,如果是则忽略,否则就存储起来!具体的实现代码如下:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<errno.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #define MODE O_RDWR #define SIZE 4096 int main(int argc,char *argv[]) { if(argc != 3) { printf("Usage: %s source_file destination_file\n",argv[0]); exit(EXIT_FAILURE); } int fd_s,fd_d; //分别用来存储读出和写入的文件内容 char buf_r[SIZE],buf_w[SIZE]; //写入缓存指针的计数器 int w_l; //read_length,write_length //读出和写入的长度 int r_len,w_len; if(-1 == (fd_s=open(argv[1],MODE))) { printf("%s[open]%s\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } if(-1 == (fd_d=open(argv[2],MODE|O_CREAT|O_TRUNC,0644))) //如果目标文件已经存在,则将其截短成0 { printf("%s[open]%s\n",argv[2],strerror(errno)); exit(EXIT_FAILURE); } //如果文件的内容过于庞大,我这里是分批存储的!且在《Unix环境高级编程》的3.9节已经论证过当SIZE为4096的时候I/O的效率最佳! while((r_len=read(fd_s,buf_r,SIZE)) > 0) { w_l=0; //将读出内容中的非空洞内容赋值到buf_w中 for(int i=0;i<r_len;i++) { if(buf_r[i] != 0) buf_w[w_l++]=buf_r[i]; } //这里得到的w_l表示的是字符数组的长度,注意数组是从0开始的 if(-1 == (w_len=write(fd_d,buf_w,w_l))) { printf("%s[write]%s\n",argv[0]+2,strerror(errno)); exit(EXIT_FAILURE); } } if(-1 == close(fd_s)) { printf("%s[close]%s\n",argv[1]+2,strerror(errno)); exit(EXIT_FAILURE); } if(-1 == close(fd_d)) { printf("%s[close]%s\n",argv[2]+2,strerror(errno)); exit(EXIT_FAILURE); } return 0; }
上面那个程序的思路就是每次读取4096字节,分批读取源文件的内容到buf_r中,然后检查buf_r的内容,如果是0则忽略,否则就暂存到buf_w中,然后将其写入到目标文件中!
检验这个程序的运行结果我用了一个较大的空洞文件,具体的运行结果如下图:
相关文章推荐
- 复制一个空洞文件且忽略掉其空洞内容
- 采用命令行方式复制任意多个文件内容到一个文件中(华科保研机试)
- [原创]VBA实现汇总excel,将多个Excel文件内容复制到一个Excel文件中
- Java-基础 文件操作IO 将文件内容复制到另外一个文件中去
- c语言初步经典题16---将一个文件的内容复制到另一个文件里面
- 编写一个应用程序实现文件的复制。使用格式:java Copy 源文件目标文件,功能是将源文件的内容复制到目标文件。
- 通过IO流讲一个文件里面的内容读到另外一个文件里面(文件复制功能的实现)
- 汇编语言: 编写一个程序,新建一个文件:d:\abc.txt,从键盘输入文件的内容(不超过100个字 符)。然后新建一个文件:d:\def.txt,将d:\abc.txt文件的内容复制到d:\def.
- 把xib文件从一个项目复制到另外一个项目,里面内容变透明的问题
- c#将一个文件夹及其里面的所有内容(文件和文件夹)复制到指定路径
- 例10.5 有一个磁盘文件,内有一些信息。要求第一次将它的内容显示在屏幕上,第二次把它复制到另一文件上。
- linux下复制一个文件的内容到另一个文件
- 一个文件的内容复制到另一个文件中.
- 系统调用,将一个文件复=中的内容复制到另一个文件中去
- 一个文件中保存一首唐诗,用字符流流进行复制,复制到新文件中的诗,所有的内容倒序输出。
- dos下将多个文件中的内容复制到一个文件中
- c语言中如何把一个文件中的内容复制到另外一个文件中的代码
- copy 一个txt文件x行到x行复制到另外一个文件/复制文件内容
- IO流_合并流读取多个文件的内容复制到一个文件中
- java复制文件的一个小例子(实现根据图片上的内容给图片重命名)