我正在尝试将图像文件加载到缓冲区中,以便通过scket发送它。我遇到的问题是程序创建一个有效大小的缓冲区,但它不会将整个文件复制到缓冲区中。我的代码如下
//imgload.cpp
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int main(int argc,char *argv){
FILE *f = NULL;
char filename[80];
char *buffer = NULL;
long file_bytes = 0;
char c = '\0';
int i = 0;
printf("-Enter a file to open:");
gets(filename);
f = fopen(filename,"rb");
if (f == NULL){
printf("\nError opening file.\n");
}else{
fseek(f,0,SEEK_END);
file_bytes = ftell(f);
fseek(f,0,SEEK_SET);
buffer = new char[file_bytes+10];
}
if (buffer != NULL){
printf("-%d + 10 bytes allocated\n",file_bytes);
}else{
printf("-Could not allocate memory\n");
// Call exit?.
}
while (c != EOF){
c = fgetc(f);
buffer[i] = c;
i++;
}
c = '\0';
buffer[i-1] = '\0'; // helps remove randome characters in buffer when copying is finished..
i = 0;
printf("buffer size is now: %d\n",strlen(buffer));
//release buffer to os and cleanup....
return 0;
}
&GT;输出
c:\Users\Desktop>imgload
-Enter a file to open:img.gif
-3491 + 10 bytes allocated
buffer size is now: 9
c:\Users\Desktop>imgload
-Enter a file to open:img2.gif
-1261 + 10 bytes allocated
buffer size is now: 7
从输出中我可以看到它为每个图像3491和1261字节分配了正确的大小(我通过窗口检查文件大小加倍并且分配的大小是正确的)但是假设复制后的缓冲区大小是9和7字节长。为什么不复制整个数据?。
答案 0 :(得分:6)
你错了。图像是二进制数据,也不是字符串数据。所以有两个错误:
1)您无法使用EOF
常量检查文件结尾。因为EOF
通常定义为0xFF,并且它是二进制文件中的有效字节。因此,使用feof()
函数检查文件结尾。或者你也可以用最大可能的方式检查文件中的当前位置(你之前用ftell()
得到了它)。
2)由于文件是二进制文件,因此中间可能包含\0
。所以你不能使用字符串函数来处理这些数据。
我也看到你使用的是C ++语言。请告诉我为什么你使用经典的C语法来处理文件?我认为使用C ++功能(如文件流,容器和迭代器)将简化您的程序。
P.S。我想说你的程序会遇到真正大文件的问题。谁知道也许你会尝试与他们合作。如果为“是”,请将ftell
/ fseek
个函数重写为int64
(long long int
)个等效项。你还需要修复阵列计数器。另一个好主意是按块读取文件。逐字节读取速度要慢得多。
答案 1 :(得分:4)
这一切都是不必要的,实际上毫无意义:
c = '\0';
buffer[i-1] = '\0';
i = 0;
printf("buffer size is now: %d\n",strlen(buffer));
请勿将strlen
用于二进制数据。 strlen
在第一个NUL
(\0
)字节处停止。二进制文件可能包含许多此类字节,因此无法使用NUL
。
-3491 + 10 bytes allocated /* There are 3491 bytes in the file. */
buffer size is now: 9 /* The first byte with the value 0. */
总之,放弃那部分。您已经拥有该文件的大小。
答案 2 :(得分:1)
您正在读取文本文件之类的二进制文件。您无法检查EOF,因为它可能位于二进制文件中的任何位置。