二进制数据长度问题

pass2000123 2009-10-27 08:23:00
void main()
{
//读文件
char pByte[600]={'\0'};
string sByte;
std::fstream fp1;
fp1.open("c:\\data1.bin", ios_base::binary|ios_base::in);
if (!fp1.is_open())
{
return;
}

fp1.read(pByte, 600);
fp1.close();

//写文件
std::fstream fp;
fp.open("c:\\data.bin", ios_base::binary|ios_base::out);
if (!fp.is_open())
{
return;
}

fp.write((char*)pByte, 600);
fp.close();
}

对二进制写入文件很陌生,看了好几篇文章还是看得似懂非懂。
一个文件我去用二进制读,问别人要用什么类型去接收?别人说可以用char 数组或string,但是读出来的东西在内存里到底怎么表示了,比如说char a[],读出来后a[1]里面是什么东西?我在VC看过是个乱码,这个乱码是和什么对应的?还有这个数组的填充长度和文件的长度有什么联系?
还有就像上面代码一样,有两个问题,第一是我不知道文件多大,但是read接口却要一个长度,第二write时也要一个长度,如果600里没有填充完,有些还是0,它也写了进去,然后结果就是新文件比旧文件多了一串0,要是长度不够就更糟了。
有没有更好的方法呢。
请各位大侠详细指教!!
...全文
710 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
pass2000123 2009-10-28
  • 打赏
  • 举报
回复
fstream file;
char *strBuf = NULL;
file.open("c:\\data1.bin", ios::binary|ios::in);
if (file.is_open())
{
file.seekg(0, ios::end);
int len = file.tellg();
file.seekg(ios::beg);
strBuf = new char[len];
file.read(strBuf, len);
}
file.close();

file.open("c:\\data.bin", ios::binary|ios::out);
if (file.is_open())
{
int a = strlen(strBuf);
int b = sizeof(strBuf);
file.write(strBuf, a);
}
file.close();

谁能告诉我 为什么 a, b 总是4呀,我要的是上面那个len值呀
Lucifer126 2009-10-28
  • 打赏
  • 举报
回复
0x00 00 00 00 00 00 00 00 00 00 00 00
| n1 | | sz1 | | n2 |
Lucifer126 2009-10-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 handongfeng 的回复:]
对二进制写入文件很陌生,看了好几篇文章还是看得似懂非懂。
一个文件我去用二进制读,问别人要用什么类型去接收?别人说可以用char 数组或string,但是读出来的东西在内存里到底怎么表示了,比如说char a[],读出来后a[1]里面是什么东西?我在VC看过是个乱码,这个乱码是和什么对应的?还有这个数组的填充长度和文件的长度有什么联系?
还有就像上面代码一样,有两个问题,第一是我不知道文件多大,但是read接口却要一个长度,第二write时也要一个长度,如果600里没有填充完,有些还是0,它也写了进去,然后结果就是新文件比旧文件多了一串0,要是长度不够就更糟了。
有没有更好的方法呢。
请各位大侠详细指教!!
[/Quote]

去研究下 结构体
比如:
strcut Test
{
int n1;
char sz1;
int n2;
}

那如果写到二进制文件的话

0x00 00 00 00 00 00 00 00 00 00 00 00
| n1 | | sz1 | | n2 |

具体,你还需要了解下 数据对齐
maning_0 2009-10-28
  • 打赏
  • 举报
回复
用数组...
字符串类会对数据流做字符串格式化..
将文件中的0x00数据当成'\0'字符,对数据流进行截断.
二进制当然是乱码....又不是字符...还有某些文件存放的文本不是char型的.比如Uncode,GBK字符就是32位表示一个字符.这样你单独读一个Char当然是乱码...
所谓二进制读文件其实就是将文件中的任何数据不作为任何一种定型的数据,而是作为一种彻底的2进制数据流来看待..
函数不会对这些数据做任何的截断,分析,调整或转义.
与文件里面到底储存了什么数据没有关系.
平凡的思想者 2009-10-28
  • 打赏
  • 举报
回复
这里有个拷贝文件的示例,你可以参考一下:
void copyfile(char *res,char *des)
{
FILE *f1;
FILE *f2;
char c='0';
char buf[100]={0};
if((f1=fopen(res,"rb"))&&(f2=fopen(des,"wb"))==NULL)
perror("open ");

int count = 0;
while(feof(f1)==0){
count = fread(buf,100,1,f1);
fwrite(buf,count,1,f2);
}

close(f1);
close(f2);
}


butwang 2009-10-28
  • 打赏
  • 举报
回复
int a = strlen(strBuf);
int b = sizeof(strBuf);

size是判断类型大小的,strBuf是个指针,指针的大小总是4字节。

strlen是判断字符串大小的,不能用来求取2进制串的大小。因为字符串是以0结尾的,而2进制没有结尾标志(必须你指定操作多少个字节),二进制串里可能包含很多0,即字符串的结束标志,所以用strlen求2进制串的大小是没意义的

int len = file.tellg();
file.write(strBuf, len); 就行了。
liem 2009-10-27
  • 打赏
  • 举报
回复
将数据按内存中存放方式放入文件中,得到的是二进制文件。
因此从二进制文件中读出数据(用fread)就象原来在内存中一样。
我们可以按一个字节(即一个字符)一个字节地读,也可以整块的读,这要根据需要。
butwang 2009-10-27
  • 打赏
  • 举报
回复
二进制是按字节操作的。
kouwenlong 2009-10-27
  • 打赏
  • 举报
回复
mark
jackyjkchen 2009-10-27
  • 打赏
  • 举报
回复
类型只是个标志,和内容无关,char[100]和int[25],长度一样,可以存储完全相同的内容;

string和CString类型不要处理二进制,会截断
平凡的思想者 2009-10-27
  • 打赏
  • 举报
回复
1、使用char[600]数组或new char[600]都可以,它不过是一段内存,内部放什么由你决定。
char只是解释地址偏移的方式。
2、每次都要记录读取的内容长度。
3、采用循环读取和写入,判断文件是否结束。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧