这是拆分大文件的正确方法吗?

时间:2014-03-21 11:45:01

标签: c

我需要将一个大图像或文本文件分成多个10个字节的块。这些块将通过UDP发送到服务器。问题是: 我不确定这段代码。这是分割文件的好方法吗? 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;

1 个答案:

答案 0 :(得分:3)

  

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

当文件由十个字符的文本块组成时,这是可以的;因为在您的情况下,文件是图片而非文字,您应该使用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数据包之前将整个文件读入内存的原因。你最好先阅读和发送相同的循环,而不是预先排队整个数据包列表。当您发送时阅读,过程的较慢部分控制整体进度。这会让你的程序使用它现在使用的一小部分内存空间,因为没有缓冲。