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

C 这是分割大文件的正确方法吗?,c,C,我需要将一个大的图像或文本文件拆分为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)) { c

我需要将一个大的图像或文本文件拆分为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;
这是分割文件的好方法吗

当文件由十个字符的文本块组成时,这是确定的;因为在您的情况下,文件是图像而不是文本,所以应该使用而不是
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数据包之前将整个文件读入内存。你最好在同一个循环中阅读和发送数据,而不是在前面排队等待一整列数据包。当您边发送边阅读时,流程中较慢的部分将控制总体进度。这将使您的程序使用它现在使用的一小部分内存空间,因为没有缓冲。

是的,对我来说很好。将
malloc
移动到
while循环之外
。从
文件
流读取字节到缓冲区,然后重新使用缓冲区。:)400KB没什么好担心的-即使手机也有几GB。在列表之后释放
标题和
数据是不是更好_append@suspectus几GB内存?IBTD.是否有任何理由将
复制到
数据
中,然后再复制到
数据包-/code>中,而不是直接复制到
数据包-/code>中?fRead()速度更快,使用的内存更少。但是,我在一些块的末尾得到“\276”。那是什么?这个数字是递增的。@WalterWhite
fread
应该只提供文件中的内容,不应该提供任何零散的数据。这可能是与使用strcpy有关的问题-如果为零,
strcpy
会提前停止,将malloc中的“堆垃圾”保留在图像中的实际字节位置。