【问题标题】:Same file with differente size fprintf on linux在Linux上具有不同大小fprintf的相同文件
【发布时间】:2017-11-03 15:55:31
【问题描述】:

我无法理解 EOF 的工作原理以及我的电脑如何知道文件的大小。

例如我做了3个文件,test0、test1和test2。 我以这种方式创建了 test0 和 test1:

int main(void) {

    /* */
    FILE* fp0 = fopen("/home/kevin/eclipse-workspaceC/FileMangment/src/test0", "w+");
    FILE* fp1 = fopen("/home/kevin/eclipse-workspaceC/FileMangment/src/test1", "w+");


    if (!fp0 || !fp1) {
        fprintf(stderr, "file pointer points to NULL\n");
        return 1;
    }

    fprintf(fp0, "abcd");
    fprintf(fp1, "abcd\n");

    fclose(fp0);
    fclose(fp1);

    return 0;
}

然后我创建了 test2,右键单击 -> 新文档并在我编写的文件中:

abcd

结尾没有空格也没有换行。 然后在 bash 我运行命令:wc -c test*; file test* 和输出:

4 test0
5 test1
5 test2
14 total
test0: ASCII text, with no line terminators
test1: ASCII text
test2: ASCII text

当我用 gedit 查看文件时,它们看起来是相同的(没有新行创建)。

我知道\n 是换行符而不是 EOF(我真的不明白这个 EOF 是什么),那么我的电脑如何知道文件何时结束?如果磁盘块大小为 4K,为什么它会在正确的字节数后停止,并且不会继续读取后面的内容?

为什么我会看到大量以这种方式解析文件的代码:

while((c=fgetc(infile))!=EOF){
putchar(c);
}

所以这意味着在某处有一个叫做 (EOF) 的字符??????? 但我在 ascii 表中找不到它。我发现值是-1.... 非常非常非常混乱……

我的电脑是在解析每个文件以了解其大小还是写在某个地方?

必须在我电脑的某个地方:

your file at position xyz has the size of blahblah...

那么这个地方在哪里?或者我应该谷歌什么? 因为我在谷歌上搜索了 3Gozzilion 之类的东西:我的文件大小存储在哪里 ecc... 并没有找到任何东西。我只想知道这些信息存储在哪里。

【问题讨论】:

  • 文件系统中的文件信息有文件的实际大小(正在使用的字节数)。 I/O 库和/或操作系统使用它来限制您可以从文件中读取的内容。
  • 没有字符是EOFfgetc 不返回 char。它在文件末尾返回一个提升为intEOF 的字符。
  • "那么我的电脑如何知道文件何时结束?"文件长度、创建/修改时间、文件名等存储在别处。此元数据通常存储在文件夹/目录中。
  • file pointer points to NULL 不是真正有用的错误消息。检查每个 fopen 之后的错误情况并使用perror 退出打印错误消息,或使用strerror
  • @chux 元数据从不存储在文件夹中,除非是完全损坏的文件系统,例如 FAT。

标签: c linux unix filesystems eof


【解决方案1】:

在 UNIX 上,每个文件对应于文件系统的一个 inode 编号。在该 inode 中,您可以找到有关文件的一些信息,包括文件大小。您可以在这里找到更多信息 : Overview of the Linux file system

【讨论】:

    【解决方案2】:

    在 unix 系统上,当您发出类似

    的命令时
    ls -l 
    

    输出与此类似

    -rw-r--r--    1 user group       393 Nov  3 22:02 README.txt
    

    这包括文件权限、所有者、组大小、创建时间、文件名等等等。

    在文件系统级别,此信息存储在 inode 中,即表示文件元数据的结构,实际上每个文件本身都由 inode 编号表示。

    在非常高的级别上,每次读取调用都会增加光标位置以读取字节。在某些时候,这将达到文件的大小。在这种情况下,读取调用甚至可能不会返回请求的文件数。例如

    观察下面的这个读取调用,我们试图从文件描述符 fd 表示的文件中读取 size 个字节。

    int nbytes = read( fd, buf, size );
    

    但是,nbytes 完全有可能是

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-14
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 2022-08-17
      • 2017-05-31
      • 2012-10-28
      相关资源
      最近更新 更多