【问题标题】:Is this the correct way of splitting a large file?这是拆分大文件的正确方法吗?
【发布时间】:2014-03-21 11:45:00
【问题描述】:

我需要将一个大的图像或文本文件分成多个 10 字节的块。这些块将通过 UDP 发送到服务器。问题是: 1.我不确定这个代码。这是拆分文件的好方法吗? 2.程序内存使用率很高。 400 KB 仅用于此功能。

int nChunks = 0;
char chunk[10];
FILE *fileToRead;
fileToRead = fopen(DEFAULT_FILENAME, "rb");

while (fgets(chunk, sizeof(chunk), fileToRead)) {
    char *data = malloc(sizeof(chunk));
    strcpy(data, chunk);

    packet *packet = malloc(sizeof(packet));
    packet->header = malloc(sizeof(packetHeader));
    packet->header->acked = 0;
    packet->header->id = ++nChunks;
    packet->header->last = 0;
    packet->header->timestamp = 0;
    packet->header->windowSize = 10;
    packet->data = data;

    list_append(packages, packet);
}


typedef struct packetHeader{
    ...
}packetHeader;

typedef struct packet{
    packetHeader *header;
    void *data;
}packet;

【问题讨论】:

  • 是的,我觉得不错。将malloc 移到while loop 之外。从FILE 流中读取字节到缓冲区,然后重用缓冲区。 :)
  • 400KB 没什么好担心的——即使手机也有几个 GB。
  • 在`list_append 之后释放headerdata
  • @suspectus 几 GB 的 RAM? IBTD。
  • 有什么理由将chunk复制到data然后复制到packet->data而不是直接复制到packet->data

标签: c


【解决方案1】:

这是分割文件的好方法吗?

当文件由十个字符的文本块组成时,这是可以的;因为在您的情况下,文件是图像,而不是文本,您应该使用 fread 而不是 fgets

此外,您应该传递sizeof(chunk),而不是sizeof(chunk)+1 作为大小。否则,fgets 会在程序分配的内存空间末尾写入一个额外的字节。

最后,您不应该使用strcpy 来复制一般数据:请改用memcpy。事实上,如果您在循环内管理缓冲区,则可以完全避免复制,如下所示:

#define CHUNK_SIZE 10
...
// The declaration of chunk is no longer necessary
// char chunk[10];
...
for (;;) {
    char *data = malloc(CHUNK_SIZE);
    size_t len = fread(data, CHUNK_SIZE, 1, fileToRead);
    if (len == 0) {
        free(data);
        break;
    }
    // At this point, the ownership of the "data" can be transferred
    // to packet->data without making an additional copy.
    ...
}

程序内存使用率很高。仅此函数需要 400 KB。

这是因为读取文件比通过 UDP 发送要快得多。这就是为什么程序在发送前几个 UDP 数据包之前设法将整个文件读入内存的原因。您最好在同一个循环中读取和发送,而不是预先将整个数据包列表排队。当您在发送时阅读,该过程中较慢的部分控制着整体进度。这将使您的程序使用它现在使用的一小部分内存空间,因为没有缓冲。

【讨论】:

  • fRead() 速度更快,使用的内存更少 25KB。但是我在一些块的末尾得到“\276”。那是什么?这个数字是递增的。
  • @WalterWhite fread 应该只为您提供文件中的内容,不应有任何杂散数据。这可能是与使用 strcpy 相关的问题 - 如果为零,strcpy 会提前停止,留下来自 malloc 的“堆垃圾”代替图像中的实际字节。
猜你喜欢
  • 1970-01-01
  • 2019-02-11
  • 2013-09-25
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
相关资源
最近更新 更多