c - Unix: write() when offset is greater than size

标签 c file unix io

我有以下代码:

 #include <ctype.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>

    char buf[]="wimpykid";
    char buff[100];
    void pri(int fd);
    int main(){
       int i=0,fd;
       fd=creat("ifile", S_IRUSR|S_IWUSR); pri(fd);
       write(fd, buf, 8); pri(fd);

       lseek(fd, 23, SEEK_CUR);  pri(fd);
       while(buf[i]!='\0'){
        if(i%2)
           buf[i]=toupper(buf[i]);i++;
       }
       write(fd, buf,8);  pri(fd);
    exit(0);
}
//print the current offset
void pri(int fd){
    printf("%d\n", lseek( fd, 0, SEEK_CUR));
}

输出为 0,8,31,39。第一次写入后,偏移量现在为 8。文件中只有 8 个字符,但如何将 23 添加到当前偏移量?如果我这样做了,当我向它写入另外 8 个字符时,这 8 个字符将从哪里开始?输出显示后 8 个字符直接跟在前 8 个字符之后。不太明白。

最佳答案

当您查看(可打印的部分)文件内容时,它可能看起来像是直接写入的两个字符序列彼此跟随:

$ cat ifile
wimpykidwImPyKiD

那是因为这里不显示不可打印的字符。 当您查看二进制数据时,您也可以看到它们:

$ hexdump -C ifile
00000000  77 69 6d 70 79 6b 69 64  00 00 00 00 00 00 00 00  |wimpykid........|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 77  |...............w|
00000020  49 6d 50 79 4b 69 44                              |ImPyKiD|
00000027

如您所见,两个字符串之间有许多零字节。这些零字节从何而来?查看 lseek 函数的手册页:

The lseek() function allows the file offset to be set beyond the end of the file (but this does not change the size of the file). If data is later written at this point, subsequent reads of the data in the gap (a "hole") return null bytes ('\0') until data is actually written into the gap.

此类文件可能会被文件系统实现为稀疏文件。

供引用:

关于c - Unix: write() when offset is greater than size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23488163/

相关文章:

c++ - 提取 PDF 的不同修订版

android - 内部存储和文件?

xml - Spring Maven 生成两个 wars windows 和 unix 相同的应用程序

bash - bash 中的语法错误

linux - bash 将每隔一个逗号更改为指向

c - "inc"includes 项目文件夹中的内容是什么?

c - 输出指定长度和和的数字

c# - 使用 Web.Net.WebClient 下载文件

java - 基于字节和基于字符的输出流

c - 通过 FIFO 传递结构