APUE Exercises 4.6

4.6 Write a utility like cp(1) that copies a file containing holes, without writing the bytes of 0 to the output file.

 

     我自己写了一整程序来完成这个操作。

     首先要使用fig3.2的程序生成一个带有hole的文件file.hole。

#include "apue.h"
#include <fcntl.h>

int main(int argc, char **argv)
{
    if (argc != 3)
        err_quit("usage: mycp <sourcefile> <destfile>");

    int fds, fdd;

    if ( (fds = open(argv[1], O_RDONLY, 0)) < 0)
        err_sys("can't open: %s", argv[1]);

    if ( (fdd = open(argv[2], O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR)) < 0)
        err_sys("can't open: %s", argv[2]);

    struct stat statbuf;
    off_t srcsize;

    if (fstat(fds, &statbuf) < 0)
        err_sys("stat error");
    srcsize = statbuf.st_size;

    char buf;
    int n;
    off_t offset = 0;

    while (offset < srcsize) {
        if ( (n = read(fds, &buf, 1)) < 0) {
            err_sys("read error");
        } else if (n > 0 && buf != 0) {
            write(fdd, &buf, n);
            offset += n;
        } else {
            offset++;
            continue;   /* ignore the hole */
        }
    }

    return 0;
}

     主要思想是这样的:先用stat()函数获得文件file.hole的大小。然后每次读取一个byte的数据,如果不是0,就把它写入到目标文件中。直至到达file.hole文件的末尾。

     可能的改进:不适用fstat()函数,只使用read()函数,一直读到文件的末尾(EOF),read()函数自会返回0,此时结束程序即可。

#include "apue.h"
#include <fcntl.h>

int main(int argc, char **argv)
{
    if (argc != 3)
        err_quit("usage: mycp <sourcefile> <destfile>");

    int fds, fdd;

    if ( (fds = open(argv[1], O_RDONLY, 0)) < 0)
        err_sys("can't open: %s", argv[1]);

    if ( (fdd = open(argv[2], O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR)) < 0)
        err_sys("can't open: %s", argv[2]);

    char buf;
    int n;
    while ( (n = read(fds, &buf, 1)) > 0) { /* read() change the 'current file offset' value in file table entry */
        if (buf != 0)
            write(fdd, &buf, n);
    }

    if (n < 0)
        err_sys("read error");

    return 0;
}


     结果:

cat@Ubuntu:~/apue/apue.2e/wangshuo$ od -c file.hole
0000000   a   b   c   d   e   f   g   h   i   j  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0040000   A   B   C   D   E   F   G   H   I   J
0040012

cat@Ubuntu:~/apue/apue.2e/wangshuo$ od -c output
0000000   a   b   c   d   e   f   g   h   i   j   A   B   C   D   E   F
0000020   G   H   I   J
0000024

原文地址:https://www.cnblogs.com/wangshuo/p/2035339.html