1, the formation of Empty Way Lseek ()
#include "apue.h"
#include <fcntl.h>
char buf1[] = "Abcdefghij";
Char buf2[] = "Abcdefghij";
int
main (void)
{
int fd;
/* Create a file */
if (fd = creat ("File.hole", File_mode)) < 0)
Err_sys ("creat error");
/* Write the first part of the content/
if (write (FD, BUF1,!=)
err_sys ("Buf1 write Error");
/* Offset now = * *
reset current offset, exceeding file length/
if (Lseek (FD, 16384, seek_set) = = 1)
err_sys ("Lseek error");
/* offset now = 16384/
* Write Part II/
if (write (FD, BUF2,)!=
err_sys ("Buf2 write Error");
/* Offset now = 16394 *
/exit (0);
}
2, by looking at the CP command source, you can see the specific process of CP:
1, to determine whether the target file exists, if present, empty the target file, if not present, create the target file
2, according to the target file's logical block size, create a copy buffer
3, to determine whether the source file has holes: File size/File Block size > block number.
4, read the source file stored to the buffer, each read a piece of
5, in the 3rd step, if there is a file hole, the buffer data to judge, if the buffer in the data is 0, it is considered that the data is empty, otherwise considered to be normal file data
6, if the data block is empty, then call Lseek, create a hole in the target file; otherwise copy buffer data to destination file
7, to determine whether the read read the source file at the end of the file, if it is, then judge whether the reading is empty, if it is empty in the final file written ""
8, repeat 1 ~ 7
9, close the target file, source files
cp An empty file, found before and after the CP occupies the size of the disk unchanged, and the SCP to another machine, the empty hole is filled up, occupy the disk block larger.
3, write their own CP command
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include < stdlib.h> #include <sys/stat.h> #define buf_size 4096 int MY_CP (const char *file1, const char *file2) {int
FD1, FD2;
Char Buffer[buf_size];
int res, current_position = 0, Byte_count =0, have_holes = 0;
struct STAT st;
FD1 = open (File1, O_RDWR);
if ( -1 = fd1) {perror ("open file1 faild");
return-1;
} if (Fstat (FD1, &st)!=0) perror ("Fstat");
else{if (S_isreg (st.st_mode) && st.st_size > St.st_blocks) {have_holes = 1;
printf ("%s is a sparse-block file!\n", file1);
} else{have_holes = 0;
printf ("%s is not a sparse-block file!\n", file1); } fd2 = open (file2, O_RDWR | O_append | O_creat |
O_trunc, 0666);
if (-1 = fd2) {perror ("open file2 faild");
return-1; } memset (Buffer, ' buf_size ', etc.
res = read (fd1, buffer, buf_size);//Returns the number of bytes read if (-1 = res) {perror ("file1 read error");
return-1;
} if (have_holes) {byte_count = 0; for (current_position = 0; current_position < res; current_position + +) {if (0!= buffer[current_position
] {Buffer[byte_count] = buffer[current_position];
Byte_count + +;
}}else Byte_count = res;
res = write (fd2, buffer, byte_count);
if (-1 = res) {perror ("File2 write error");
return-1;
Close (FD1);
Close (FD2);
int main (int argc, char * argv[]) {if (3!= argc) {printf ("Usage error:./a.out file1 file2\n");
return-1;
int res = MY_CP (argv[1], argv[2]);
if (-1 = res) {perror ("MY_CP error");
return-1;
} exit (0); }
The CP command replicates up to 4096 bytes, but it does determine that there is a hole in the Shifou depending on the size of the file and the size of the block actually occupied