Copy an empty file and ignore its empty content
First of all, what is called an empty file! For example, the following code:
1#include <stdio.h>2#include <string.h>3#include <stdlib.h>4#include <errno.h>5#include <sys/types.h>6#include <sys/stat.h>7#include <fcntl.h>8#include <unistd.h>9 Ten #defineMODE o_creat| o_rdwr| O_trunc One intMainintargcChar*argv[]) A { - intFD; - the if(ARGC! =2) - { -printf"usage:%s <filename>\n", argv[0]); - exit (exit_failure); + } - if(-1= = (Fd=open (argv[1],mode,0644))) + { Aprintf"%s[open]%s\n", argv[0],strerror (errno)); at exit (exit_failure); - } - if(-1= = Write (FD,"ABCDE",5)) - { -printf"%s[write]%s\n", argv[0],strerror (errno)); - exit (exit_failure); in } - if(-1= = Lseek (FD,5, seek_end)) to { +printf"%s[lseek]%s\n", argv[0],strerror (errno)); - exit (exit_failure); the } * if(-1= = Write (FD,"ABCDE",5)) $ {Panax Notoginsengprintf"%s[write]%s\n", argv[0],strerror (errno)); - exit (exit_failure); the } + if(-1==Close (FD)) A { theprintf"%s[close]%s\n", argv[0],strerror (errno)); + exit (exit_failure); - } $printf"empty files have been created successfully! \ n"); $ return 0; -}
In this code, I first write abcde five bytes in the file, and then move the file pointer back 5 bytes from the end of the file, then write the contents of ABCDE5 bytes! So in this file, two times in the middle of the ABCDE will produce a 5 byte hole, this empty content is written in 0. The hole in the file does not require the storage area on disk, the specific processing method and the implementation of the file system is related! If I open this file with VIM, it will be the effect!
The ^@ in the middle of the blue means 0 empty!
Next, let's talk about how to copy an empty file, and let the contents of the empty part of it be ignored! Here we take advantage of this feature with empty content of 0! The specific implementation method is to read the contents of the file value is 0, if it is ignored, otherwise stored! The specific implementation code is as follows:
#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>#defineMODE O_rdwr#defineSIZE 4096intMainintargcChar*argv[]) { if(ARGC! =3) {printf ("Usage:%s source_file destination_file\n", argv[0]); Exit (Exit_failure); } intFd_s,fd_d; //to store the contents of the read and write files, respectively CharBuf_r[size],buf_w[size]; //counters written to cache pointers intw_l;//Read_length,write_length//read-out and write length intR_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)))//if the target file already exists, truncate it to 0{printf ("%s[open]%s\n", argv[2],strerror (errno)); Exit (Exit_failure); } //if the content of the file is too large, I am storing it in batches! And in the UNIX Environment Advanced Programming Section 3.9 has demonstrated that the size of 4096 of the time I/O is the best efficiency! while((R_len=read (fd_s,buf_r,size)) >0) {w_l=0; //assigning non-empty content in the read-out content to Buf_w for(intI=0; i<r_len;i++) {if(Buf_r[i]! =0) buf_w[w_l++]=Buf_r[i]; }//The resulting w_l represents the length of the character array, noting that the array is starting from 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;}
The idea of the above program is to read 4096 bytes each time, read the contents of the source file in batches to Buf_r, and then check the contents of Buf_r, if 0 is ignored, otherwise it will be staged to Buf_w, and then write it to the target file!
Check the running results of this program I used a large empty file, the specific results such as:
Copy an empty file and ignore its empty content