【问题标题】:Writing empty file doesn't write file, writing too large file writes empty file写空文件不写文件,写太大文件写空文件
【发布时间】:2019-08-23 13:44:45
【问题描述】:

我正在为FUSE 程序编写文件操作。但是我在使用file_operations.write 函数时遇到了一些问题。我遇到的问题是:

  • 试图写入一个空文件(在 vim 中打开并立即保存,所以它说 0L 0C 已写入)它根本不写入并且保持内容不变,所以如果文件之前包含“文本”它仍然会包含“文本”。
  • 尝试写入大文件(约 10KB)将导致文件为空。

对于空文件部分。我已经尝试了几件事,例如检查大小是否小于 1,(我假设这是写入空文件时给定的大小)并简单地将 char* 指向单个 '\0' 字节。

我也尝试了单独的 if 案例,发现大小为 -2 出于某种奇怪的原因,但是当我尝试按照上面解释的方式编写一个空文件时,发现 -2 时,它仍然不起作用。

对于太大的文件,我不知道。

static int fs_write(const char* path, const char* buffer, size_t size, off_t offset, struct fuse_file_info* ffinfo) {
  // Find the associated file_t* and dir_t* to the file.
  file_t* file = get_file_from_path(path);
  dir_t* directories = get_parents_from_path(path);

  // The contents of a file are stored in a char* so I have to realloc
  // the previous pointer and memcpy the new contents from buffer to
  // file->contents, using size and offset as an indication of how large
  // to make the realloc and what to copy over.

  char* file_contents_new = (char*) realloc(file->contents, (size + 1) * sizeof(char));

    // realloc failed
    if (file_contents_new == NULL)
        return -ENOMEM;

    //  point the previous file contents pointer to the newly allocated section.
    file->contents = file_contents_new;

    // Copy from buffer+offset to the file contents with the size provided.
    memcpy(file->contents, buffer + offset, size);

    *(file->contents + size) = '\0'; // Append NULL char to end file string.

    return size;
}

在这里,我也希望对空文件和大文件进行适当的处​​理,因为:

  • 大小 0(这对我来说最有意义)将重新分配到大小为 0+1 的 char*(1 表示空字节)
  • 然后将文件->内容指向它
  • 然后将0字节从缓冲区复制到文件->内容
  • '\0'字符写入文件末尾->内容(大小为length of the realloc'ed block - 1);在这种情况下,在第 0 个索引处写入 '\0'
  • 返回写入的大小,在本例中为 0。

但是,vim 关闭时报告它已将 0L 0C 写入文件,但该文件未被触及。

大文件:

  • 该函数将多次调用 write 以将块写入文件
  • 然而写入的是一个空文件。

【问题讨论】:

  • 您的realloc 调用看起来很奇怪,不应该是realloc(file->contents, size + file->size); 之类的吗?
  • @Mathieu 我试过realloc(file->contents, strlen(file->contents) + use_size + 1); 它没有改变任何东西。我假设size 是缓冲区的新大小。它不会追加数据,而是覆盖数据。因此,如果我想将“test”写入文件,它将重新分配到大小为 4+1 的 char* 以生成“test\0”。所以我只重新分配4+1 * sizeof(char) 写“测试”然后附加空字节。
  • 这个函数每次都会用新值覆盖文件内容。你需要展示你是如何调用这个函数的。

标签: c memcpy fuse


【解决方案1】:

我不习惯 FUSE,但我认为您没有很好地使用参数(请参阅https://github.com/libfuse/libfuse/blob/master/example/passthrough.c

  • buffer:要写入的数据
  • size: 缓冲区大小
  • offset: 写入文件的位置。

所以你的代码看起来像:

static int fs_write(const char* path, const char* buffer, size_t size, off_t offset, struct fuse_file_info* ffinfo) 
{
  // Find the associated file_t* and dir_t* to the file.
  file_t* file = get_file_from_path(path);
  dir_t* directories = get_parents_from_path(path);


    /* realloc to store data. Note the +1 to store the final \0 */
    char* file_contents_new = realloc(file->contents, file->size + size+1);

    // realloc failed
    if (file_contents_new == NULL)
        return -ENOMEM;


    //  point the previous file contents pointer to the newly allocated section.
    file->contents = file_contents_new;

    /* update size too, without to +1 to prevent adding one at each write call */
    file->size = file->size + size;

    // Copy buffer to the file taking offset into account
    memcpy(file->contents + offset, buffer, size);

    /* Append NULL char to end file string. */
    *(file->contents + file->size) = '\0'; 

    return size;
}

【讨论】:

  • 问题可能是我用来弄清楚“偏移”是什么意思的来源。他们将其描述为- offset: offset from where chunk should start,我将其解释为缓冲区中的偏移量。但在文件上使用偏移量更有意义。
  • 但是,它仍然没有修复。是否有可能写入失败,因为读取功能也错误?还是应该不影响写作。
猜你喜欢
  • 2023-03-27
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多