2011-12-19 38 views
0

在“Unix环境下的高级编程”示例中,下面的示例程序创建一个文件,然后使用lseek将文件指针移动到更远的位置地址,从而在文件中放置一个“洞”。作者说中间的空间充满了“0”。我想看看这些“0”是否会打印出来。所以我稍微修改了程序。但是我注意到只有有效的字符被写入到文件中。APUE:创建一个洞中的文件:图3.2第65页

我的问题是,Unix/Linux文件系统管理器如何知道不打印中间的字节?

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

char buf1[] = "abcdefghij"; 
char buf2[] = "ABCDEFGHIJ"; 
char buf3[10]; 

int 
main(void) 
{ 
    int fd; 

    if ((fd = creat("file.hole", FILE_MODE)) < 0) { 
    err_sys("creat error"); 
    } 

    if (write(fd, buf1, 10) != 10) {            /* offset is now = 10 */ 
    err_sys("buf1 write error"); 
    } 

    if (lseek(fd, 16380, SEEK_SET) == -1) {          /* offset now = 16380 */ 
    err_sys("lseek error"); 
    } 

    if (write(fd, buf2, 10) != 10) {            /* offset now = 16390 */ 
    err_sys("buf2 write error"); 
    } 
    close(fd); 

    if ((fd = open("file.hole", O_RDWR)) == -1) { 
    err_sys("failed to re-open file"); 
    } 

    ssize_t n; 
    ssize_t m; 
    while ((n = read(fd, buf3, 10)) > 0) { 
    if ((m = write(STDOUT_FILENO, buf3, 10)) != 10) { 
     err_sys("stdout write error"); 
    } 
    } 

    if (n == -1) { 
    err_sys("buf3 read error"); 
    } 
    exit(0); 
} 
+0

此外,我认为你的代码中有一个错误,它可能会在文件结束后写入多达9个字节的垃圾(或者甚至可能转储违规),以防止更改代码的其余部分以输出不能被10整除的字节数。为避免这种情况,请将上一个“写入”行(循环中的一个)中的“10”更改为“n”。 – Amadan 2011-12-20 01:16:13

回答

3

字符\000具有空宽度的显示表示。它是印刷的,但它的印刷是不可见的。并非每个代码点都是一个字符。以同样的方式,\n被打印为换行符,而不是字符。

+0

要看到这一点,请尝试将程序的输出传输到以可打印格式显示不可打印字符的东西,例如'cat -A','od -c'或less。请注意,您将获得*很多输出。 – 2011-12-20 00:55:29

+0

或'hexdump -C文件| less' – Amadan 2011-12-20 01:13:39

+0

假设你已经将程序的输出重定向到'file'。或者只是'./program | hexdump -C | less'。 – 2011-12-20 01:15:42