为了通过套接字发送文件,我一直在试图将文件分成块。我可以轻松地读/写文件而不将其分成块。下面的代码运行,工作,有点。它将编写一个文本文件并具有垃圾字符。如果这只是为了txt,没问题。 Jpegs没有使用垃圾。
已经有几天了,所以我完成了我的研究,是时候得到一些帮助了。我确实想严格遵守二进制阅读器,因为这需要处理任何文件。
我见过很多光滑的例子。 (没有一个用jpgs为我工作)大多数情况下是while(文件)...我订阅了,如果你知道大小,使用for循环,而不是while循环阵营。
感谢您的帮助!!
vector<char*> readFile(const char* fn){
vector<char*> v;
ifstream::pos_type size;
char * memblock;
ifstream file;
file.open(fn,ios::in|ios::binary|ios::ate);
if (file.is_open()) {
size = fileS(fn);
file.seekg (0, ios::beg);
int bs = size/3; // arbitrary. Actual program will use the socket send size
int ws = 0;
int i = 0;
for(i = 0; i < size; i+=bs){
if(i+bs > size)
ws = size%bs;
else
ws = bs;
memblock = new char [ws];
file.read (memblock, ws);
v.push_back(memblock);
}
}
else{
exit(-4);
}
return v;
}
int main(int argc, char **argv) {
vector<char*> v = readFile("foo.txt");
ofstream myFile ("bar.txt", ios::out | ios::binary);
for(vector<char*>::iterator it = v.begin(); it!=v.end(); ++it ){
myFile.write(*it,strlen(*it));
}
}
答案 0 :(得分:2)
问题是你使用strlen来计算要写入的数组的大小。一个0是二进制的一部分,你不会写出正确的大小。相反,使用一对char *,int,其中int指定要写入的大小,您将是黄金。 像:
#include <iostream>
#include <vector>
#include <fstream>
#include <stdlib.h>
#include <string.h>
using namespace std;
ifstream::pos_type fileS(const char* fn)
{
ifstream file;
file.open(fn,ios::in|ios::binary);
file.seekg(0, ios::end);
ifstream::pos_type ret= file.tellg();
file.seekg(0,ios::beg);
ret=ret-file.tellg();
file.close();
return ret;
}
vector< pair<char*,int> > readFile(const char* fn){
vector< pair<char*,int> > v;
ifstream::pos_type size;
char * memblock;
ifstream file;
file.open(fn,ios::in|ios::binary|ios::ate);
if (file.is_open()) {
size = fileS(fn);
file.seekg (0, ios::beg);
int bs = size/3; // arbitrary. Actual program will use the socket send size
int ws = 0;
int i = 0;
cout<<"size:"<<size<<" bs:"<<bs<<endl;
for(i = 0; i < size; i+=bs){
if(i+bs > size)
ws = size%bs;
else
ws = bs;
cout<<"read:"<<ws<<endl;
memblock = new char [ws];
file.read (memblock, ws);
v.push_back(make_pair(memblock,ws));
}
}
else{
exit(-4);
}
return v;
}
int main(int argc, char **argv) {
vector< pair<char*,int> > v = readFile("a.png");
ofstream myFile ("out.png", ios::out | ios::binary);
for(vector< pair<char*,int> >::iterator it = v.begin(); it!=v.end(); ++it ){
pair<char*,int> p=*it;
myFile.write(p.first,p.second);
}
}
答案 1 :(得分:1)
myFile.write(*it,strlen(*it));
在二进制数据上使用字符串长度。我怀疑那是你的罪魁祸首。如果没有,那肯定是code-smell。
答案 2 :(得分:0)
你永远不应该这样做:
myFile.write(*it,strlen(*it));
二进制数据。 strlen
计算字节,直到它到达一个包含0的字节(我们想说的是NUL
,但这是一个诚实的0)。如果您阅读了足够多的二进制数据,那么您将获得一个NUL,并且您将得到一个简短的计数。但实际情况可能会更糟糕,因为没有地方存储NUL for strlen来查找。你只是指望在数据块结束时有一个你读取文件到。
所以不要这样做。记住每个块中的字节数(您可以使用向量&gt;但是还有很多类似C ++的可能性)并使用它来编写数据。