为什么我的 ofstream 写入导致比预期更多的字节?
Why does my ofstream write result in more bytes than expected?
编辑 1:我已经确定了触发此问题的十六进制组合,但仍无法修复它。请参阅底部的编辑:
原文Post:我正在尝试将数据从传感器传递到二进制文件。我正在使用制造商的示例代码和 DLL 一次获取 4096 个字节,然后尝试将其写入文件。我的最终文件大小在 4100 到 4114 字节之间变化,额外的位随机分布在整个文件中。
来自传感器的数据以 4096 长无符号字符结束。当我将每个字符发送到 std::cout 时,值都是正确的(因此传感器和与之通信的 DLL 正在工作)。但是,将整个字符写入二进制文件(使用 ofstream::write)和一次写入一个字符(使用 ofstream::put)一样失败。在下面的代码中,我删除了文件创建等的错误检查。
unsigned int uiread = 4096;
unsigned char ccdbuf[4096];
ofstream ofile;
/* DLL call stuff removed since it's hardware-specific */
ofile.open("camdata.bin");
// ofile.write(reinterpret_cast<const char*>(ccdbuf), uiread); // 4100 - 4114
for (int ii = 0; ii < uiread; ii++)
{
std::cout << (int)ccdbuf[ii] << "\n";
ofile.put(ccdbuf[ii]); // 4100 - 4114
// ofile.put(5); // 4096
}
ofile.close();
被注释掉的 'ofile.write' 行是传感器制造商提供给我的。末尾的注释突出显示生成的文件长度从 4100 到 4114 字节不等,额外的位散布在整个文件中。
for 循环中的 'std::cout' 行显示了正确的值。
如果我写“5”4096 次,则该文件正是我所期望的(4096 字节)。但是,一次写入一个 char 向量会导致二进制记录长度可变(长于 4096),额外位的位置是随机的。
我怀疑我的问题出在从 unsigned char 到 ofstream::write 预期类型(const char?)的转换上,但我不知道如何解决它。提前致谢。
编辑 1:
我已经确定最初触发此行为的双字节字符串始终以 0x0A 结尾,但第一个不正确写入的数据实际上是该对的第一个字节。因此,发送到 std:cout 的文本输出的十六进制等效值可能是 0x890A、0xC00A 或 0xC20A,但当输出中断时,该字节对始终写入 0x0A0D。
查看构成第一个字节的位似乎并没有揭示 0x0A 之前的位模式,而且并非以 0x0A 结尾的每个双字节对都会触发错误。由于 ofstream::put 在 for 循环内,所以我觉得第一个写入错误是值 0x0A 之前的循环似乎很奇怪。
正如问题的评论中所指出的,通过不显式地将写入文件作为二进制文件打开 Windows 偶尔会修改写入。修改 ofstream::open 命令以包含二进制标志已解决问题。
ofile.open("camdata.bin", ios_base::binary);
替换
ofile.open("camdata.bin");
编辑 1:我已经确定了触发此问题的十六进制组合,但仍无法修复它。请参阅底部的编辑:
原文Post:我正在尝试将数据从传感器传递到二进制文件。我正在使用制造商的示例代码和 DLL 一次获取 4096 个字节,然后尝试将其写入文件。我的最终文件大小在 4100 到 4114 字节之间变化,额外的位随机分布在整个文件中。
来自传感器的数据以 4096 长无符号字符结束。当我将每个字符发送到 std::cout 时,值都是正确的(因此传感器和与之通信的 DLL 正在工作)。但是,将整个字符写入二进制文件(使用 ofstream::write)和一次写入一个字符(使用 ofstream::put)一样失败。在下面的代码中,我删除了文件创建等的错误检查。
unsigned int uiread = 4096;
unsigned char ccdbuf[4096];
ofstream ofile;
/* DLL call stuff removed since it's hardware-specific */
ofile.open("camdata.bin");
// ofile.write(reinterpret_cast<const char*>(ccdbuf), uiread); // 4100 - 4114
for (int ii = 0; ii < uiread; ii++)
{
std::cout << (int)ccdbuf[ii] << "\n";
ofile.put(ccdbuf[ii]); // 4100 - 4114
// ofile.put(5); // 4096
}
ofile.close();
被注释掉的 'ofile.write' 行是传感器制造商提供给我的。末尾的注释突出显示生成的文件长度从 4100 到 4114 字节不等,额外的位散布在整个文件中。
for 循环中的 'std::cout' 行显示了正确的值。
如果我写“5”4096 次,则该文件正是我所期望的(4096 字节)。但是,一次写入一个 char 向量会导致二进制记录长度可变(长于 4096),额外位的位置是随机的。
我怀疑我的问题出在从 unsigned char 到 ofstream::write 预期类型(const char?)的转换上,但我不知道如何解决它。提前致谢。
编辑 1: 我已经确定最初触发此行为的双字节字符串始终以 0x0A 结尾,但第一个不正确写入的数据实际上是该对的第一个字节。因此,发送到 std:cout 的文本输出的十六进制等效值可能是 0x890A、0xC00A 或 0xC20A,但当输出中断时,该字节对始终写入 0x0A0D。
查看构成第一个字节的位似乎并没有揭示 0x0A 之前的位模式,而且并非以 0x0A 结尾的每个双字节对都会触发错误。由于 ofstream::put 在 for 循环内,所以我觉得第一个写入错误是值 0x0A 之前的循环似乎很奇怪。
正如问题的评论中所指出的,通过不显式地将写入文件作为二进制文件打开 Windows 偶尔会修改写入。修改 ofstream::open 命令以包含二进制标志已解决问题。
ofile.open("camdata.bin", ios_base::binary);
替换
ofile.open("camdata.bin");