C++ fread丢失二进制数据
我正在使用fread函数读取通过TCP发送的文件。我发现,如果文件是二进制的,fread不会读取整个文件。我尝试了我在网上找到的所有东西,但没有任何帮助。我的代码是:C++ fread丢失二进制数据,c++,c,C++,C,我正在使用fread函数读取通过TCP发送的文件。我发现,如果文件是二进制的,fread不会读取整个文件。我尝试了我在网上找到的所有东西,但没有任何帮助。我的代码是: #define BUFSIZE 1024 char buf[BUFSIZE]; FILE *file = fopen(soubor,"rb"); //I do a check which i won't write here size_t bytes_loaded = 0; while (!feof(file))
#define BUFSIZE 1024
char buf[BUFSIZE];
FILE *file = fopen(soubor,"rb"); //I do a check which i won't write here
size_t bytes_loaded = 0;
while (!feof(file))
{
bytes_loaded = fread(buf,1,BUFSIZE,file);
if(bytes_loaded != BUFSIZE)
{
if(!feof(file))
{
for(int i = 0; i < 100;i++)
{
fseek(file,-strlen(buf),SEEK_CUR);
bytes_loaded = fread(buf,1,BUFSIZE,file);
if(bytes_loaded == BUFSIZE)
{
break;
}
else if(i == 99)
{
fprintf(stderr,"C could't read the file\n");
fclose(file);
close(client_socket);
return 1;
}
}
}
}
bytestx = send(client_socket, buf, BUFSIZE, 0);
if (bytestx < 0)
perror("ERROR in sendto");
bzero(buf, BUFSIZE);
bytes_loaded = 0;
}
#定义BUFSIZE 1024
字符buf[BUFSIZE];
FILE*FILE=fopen(soubor,“rb”)//我做了一张支票,我不会在这里写
大小\u t字节\u加载=0;
而(!feof(文件))
{
加载的字节=fread(buf,1,BUFSIZE,file);
if(已加载字节数!=BUFSIZE)
{
如果(!feof(文件))
{
对于(int i=0;i<100;i++)
{
fseek(文件,-strlen(buf),SEEK_CUR);
加载的字节=fread(buf,1,BUFSIZE,file);
if(字节数_加载==BUFSIZE)
{
打破
}
否则如果(i==99)
{
fprintf(stderr,“C无法读取文件\n”);
fclose(文件);
关闭(客户端_套接字);
返回1;
}
}
}
}
bytestx=send(客户机_套接字,buf,BUFSIZE,0);
if(bytestx<0)
perror(“发送错误”);
bzero(buf,BUFSIZE);
加载的字节数=0;
}
我做错什么了吗?例如,fread check…您的整个fread()
错误处理是错误的,请将其清除(在二进制缓冲区上使用strlen()
无论如何都是错误的)
事实上,您不应该使用feof()
来控制循环。只需在循环中调用fread()
,直到它在EOF或error时返回<1(使用feof()
和ferror()
进行区分)。当它返回>0时,您需要将该值传递给send
,而不是传递BUFSIZE
尝试类似以下内容:
#define BUFSIZE 1024
char buf[BUFSIZE], *pbuf;
FILE *file = fopen(soubor, "rb");
...
size_t bytes_loaded;
do
{
bytes_loaded = fread(buf, 1, BUFSIZE, file);
if (bytes_loaded < 1)
{
if ((!feof(file)) && ferror(file))
fprintf(stderr, "Couldn't read the file\n");
break;
}
pbuf = buf;
do
{
bytestx = send(client_socket, pbuf, bytes_loaded, 0);
if (bytestx < 0)
{
perror("ERROR in send");
break;
}
pbuf += bytestx;
bytes_loaded -= bytestx;
}
while (bytes_loaded > 0);
}
while (bytes_loaded == 0);
fclose(file);
...
#定义BUFSIZE 1024
char buf[BUFSIZE],*pbuf;
FILE*FILE=fopen(soubor,“rb”);
...
加载的字节大小;
做
{
加载的字节=fread(buf,1,BUFSIZE,file);
如果(加载的字节数小于1)
{
如果((!feof(文件))和&ferror(文件))
fprintf(stderr,“无法读取文件”\n);
打破
}
pbuf=buf;
做
{
bytestx=send(客户端套接字,pbuf,加载的字节数,0);
if(bytestx<0)
{
perror(“发送错误”);
打破
}
pbuf+=bytestx;
加载的字节数-=bytestx;
}
while(加载的字节数>0);
}
while(加载的字节数=0);
fclose(文件);
...
如果您只是将字节从文件转移到套接字,那么您可以继续循环std::fread
的返回值,该返回值告诉您读取了多少字节,然后将这些字节准确地发送到send()
命令
类似以下(未测试)代码:
if(文件*fp=std::fopen(soubor,“rb”))
{
char-buf[1024];
标准:大小字节数;
而((bytesrx=std::fread(0,1,sizeof(buf),fp))>0)
{
int-bytestx;
if((bytestx=send(客户端_套接字,buf,bytesrx,0)<0))
{
//套接字错误
std::是否有这个问题,不知道这是否是你的问题:-请阅读它,也可能是重复的,strlen(buf)
仅适用于文本,不适用于二进制数据。您不会总是准确地读入BUFSIZE
字节,因此您不应该总是发送BUFSIZE
字节。您应该发送读取的字节数,从fread()返回的值是什么时候
call。我试过了,但仍然无法加载整个文件。我正在尝试pdf文件,从300 KB得到122KB@Erik然后,您在尚未显示的代码中犯了其他错误。请编辑您的问题以显示您的recv
代码。问题在于使用strlen,它确实做了很多事情。Sizeof效果更好
if(FILE* fp = std::fopen(soubor, "rb"))
{
char buf[1024];
std::size_t bytesrx;
while((bytesrx = std::fread(0, 1, sizeof(buf), fp)) > 0)
{
int bytestx;
if((bytestx = send(client_socket, buf, bytesrx, 0) < 0))
{
// socket error
std::cout << "socket error: " << std::strerror(errno) << '\n';
return EXIT_FAILURE;
}
}
if(bytesrx < 0)
{
// file error
std::cout << "file error: " << std::strerror(errno) << '\n';
return EXIT_FAILURE;
}
}
else
{
// error opening file
}