代码之家  ›  专栏  ›  技术社区  ›  gsamaras a Data Head

我在文件中读的比写的多

  •  0
  • gsamaras a Data Head  · 技术社区  · 10 年前

    我有一个文件,按固定大小的块分区。我正在复制 test_file.txt 插入文件的第三个块。我读取并复制了18个字节。

    然后,我试图从文件中复制我刚刚导入到新创建的.txt文件中的同一个.txt文件,但我正在向新文件写入256个字节。而且,当我试图阅读它时,它充满了垃圾。

    第一个函数用于导入.txt,第二个函数用于导出.txt。

    void copy_file(int mfs_desc, char* filename, Superblock* s, MDS mds) {
      if(mds.size == 0)
        return;
      char buffer[s->block_size];
      int i = 0;
      for (; i < s->block_size; ++i) {
        buffer[i] = '\0';
      }
    
      int source_desc = open(filename, O_RDONLY);
      // error handling
      if (source_desc == -1) {
        perror("opening file in copy file");
        exit(1);
      }
    
      ssize_t nread;
      int total = 0;
    
      off_t seek = lseek(mfs_desc,
                   sizeof(Superblock) + mds.datablocks[0] * s->block_size,
                   SEEK_SET);
      printf("offset = %d\n", mds.datablocks[0]);
      if (seek < 0) {
        perror("seek");
        exit(1);
      }
    
      total = 0;
      while ((nread = read(source_desc, buffer, s->block_size)) > 0) {
        total += nread;
        write(mfs_desc, buffer, s->block_size);
      }
      printf("read and copied: %d bytes\n", total);
    
      if (close(source_desc) == -1) {
        perror("closing file in copy file");
        exit(1);
      }
    }
    
    int copy_file_export(int mfs_desc, char* filename, Superblock s, MDS mds) {
      if(mds.size == 0) {
        printf("File is empty, abort\n");
        return 0;
      }
      char buffer[s.block_size];
      int i = 0;
      for (; i < s.block_size; ++i) {
        buffer[i] = '\0';
      }
    
      int destination_desc = open(filename, O_CREAT | O_WRONLY);
      // error handling
      if (destination_desc == -1) {
        printf("filename = |%s|\n", filename);
        perror("opening file in copy file export");
        exit(1);
      }
    
      ssize_t nread;
      int total = 0;
    
      off_t seek = lseek(mfs_desc,
                   sizeof(Superblock) + mds.datablocks[0] * s.block_size,
                   SEEK_SET);
      printf("offset = %d\n", mds.datablocks[0]);
      if (seek < 0) {
        perror("seek");
        exit(1);
      }
      for(i = 0; i < mds.size; ++i) {
        nread = read(mfs_desc, buffer, s.block_size);
        total += nread;
        write(destination_desc, buffer, nread);
      }
      printf("wrote: %d bytes\n", total);
    
      if (close(destination_desc) == -1) {
        perror("closing file in copy file");
        exit(1);
      }
      return 1;
    }
    

    输出:

    import test_file.txt ... / <-- just a command
    offset = 2
    read and copied: 18 bytes
    export test_file.txt ... ../../ <-- just a command
    offset = 2
    wrote: 256 bytes
    

    我做错了什么?

    2 回复  |  直到 10 年前
        1
  •  1
  •   JuniorCompressor    10 年前

    我会替换

    write(mfs_desc, buffer, s->block_size);

    具有

    write(mfs_desc, buffer, nread);

        2
  •  1
  •   gsamaras a Data Head    10 年前

    在这段代码中:

    while ((nread = read(source_desc, buffer, s->block_size)) > 0) {
        total += nread;
        write(mfs_desc, buffer, s->block_size);
    }
    

    你很可能会处理最后一个 write() 不正确。您只需要写入读取的字节。

        write(mfs_desc, buffer, nread);
    

    此外,这些行很可能是假的:

    char buffer[s->block_size];
    
    char buffer[s.block_size];
    

    您正在尝试对堆栈上的数组使用可变大小的分配。你不能这么做。这些分配必须是固定的(编译时间常数)大小。