我需要将一个大图像或文本文件分成多个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;
答案 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数据包之前将整个文件读入内存的原因。你最好先阅读和发送相同的循环,而不是预先排队整个数据包列表。当您发送时阅读,过程的较慢部分控制整体进度。这会让你的程序使用它现在使用的一小部分内存空间,因为没有缓冲。