• 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

  • 相关阅读:
    HDU 2888 Check Corners (模板题)【二维RMQ】
    POJ 3264 Balanced Lineup(模板题)【RMQ】
    poj 3368 Frequent values(经典)【RMQ】
    SPOJ RPLN (模板题)(ST算法)【RMQ】
    UVA 796 Critical Links(模板题)(无向图求桥)
    UVA 315 Network (模板题)(无向图求割点)
    POJ 2029 Get Many Persimmon Trees (模板题)【二维树状数组】
    poj 3067 Japan 【树状数组】
    POJ 2481 Cows 【树状数组】
    POJ 1195 Mobile phones【二维树状数组】
  • 原文地址:https://www.cnblogs.com/wangshuo/p/2035339.html
Copyright © 2020-2023  润新知