【问题标题】:Fragmenting and Un-fragmenting files in C在 C 中对文件进行分段和取消分段
【发布时间】:2013-04-13 20:51:04
【问题描述】:

我想把一个文件(文本或二进制文件)分片成一定大小(大约 250-500kB)的小块,将分片的顺序随机化,然后放到另一个临时分片文件中。

然后,非碎片化将获取碎片文件,提取碎片,将它们按顺序排列并让原始文件完好无损。

这对于简单的基于文本的 ASCII 文件来说非常容易,因为您可以使用 C 库函数(如 sscanf)来格式化/解析信息。一个文件的格式可以像

(#### <fragment #> <fragment> ...)

但是,我不确定如何处理二进制文件。

我知道一个简单的解决方案是对像 <.part1 .part2> 文件这样的片段使用单独的文件,但这会有点难看,并且不能很好地扩展到更大的文件。将其存储在一个文件中会更好。

非常感谢。

【问题讨论】:

  • 听起来像是默默无闻的安全。无论如何,您可以继续将元数据存储为纯文本并像以前一样使用sscanf。您应该查看 fread (cplusplus.com/reference/cstdio/fread) 以直接处理二进制数据。
  • 我想通了。我只是有点担心能够再次提取文件片段以按顺序形成整个文件。使用文本,您可以确保标签格式保持一致。对于二进制我不太确定。
  • 需要添加每个chunk的大小:{#chunk ID, chunk size, data } ....
  • 您必须澄清问题。通常二进制比文本更可靠。
  • 你能分享一下你已经做了什么吗?

标签: c file parsing temporary-files


【解决方案1】:

对二进制文件执行此操作是最简单的,也是最快和最可靠的。您的片段文件需要一个简单的段记录,它为您提供原始文件中的偏移量和段的长度。记录可能如下所示:

typedef struct _Fragment
{
    unsigned long offset;
    unsigned long length;
} Fragment;

编写文件将如下所示:

Fragment fragment;
FILE *outFile;
unsigned long segmentOffset, segmentLength;
char segmentData[MAXSEGMENTLENGTH];

outFile = fopen(fileName, "wb");

while (ReadNextSegment(segmentData, &segmentOffset, &segmentLength))
{
    fragment.offset = segmentOffset;
    fragment.length = segmentLength;

    fwrite(header, sizeof(fragment), 1, outFile);
    fwrite(segmentData, 1, segmentLength, outFile);
}

fclose(outFile);

重新组装文件是通过颠倒过程来完成的。读取每条Fragment记录,然后使用fragment.length读取fread下面的数据,然后使用fseek函数和fragment.offset定位到目标文件中正确的偏移量,然后使用fwrite写入.

【讨论】:

    【解决方案2】:

    尽量只使用二进制数据。在你的碎片文件中,遵循以下结构:

    OFFSET SIZE  DESCRIPTION
         0    4  BLOCK NUMBER
         4    4  BLOCK SIZE IN BYTES
         8    ?  BLOCK DATA
    

    定义一个头结构:

    typedef struct hdr
    {
        uint32_t number;
        uint32_t size;
    } hdr_t;
    

    使用它的代码可能如下所示:

    void file_append(FILE *f, size_t block, size_t size, const void *data)
    {
        hdr_t hdr;
        hdr.number = block;
        hdr.size = size;
        fwrite(&hdr, sizeof(hdr), 1, f);
        fwrite(data, size, 1, f);
    }
    

    并读取数据:

    void file_read_chunk(FILE *f, size_t *block, size_t *size, void **data)
    {
        hdr_t hdr;
    
        fread(&hdr, sizeof(hdr), f);
        *block = hdr.number;
        *size = hdr.size;
        *data = malloc(hdr.size);
        fread(*data, hdr.size, 1, f);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      • 1970-01-01
      • 2020-11-30
      • 2014-05-02
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多