我已将其中一个错误隔离到一个简单的字节序列中,我似乎无法正确传输。请查看以下代码段:
#include <iostream>
int main(int argc, char** argv) {
long long l = 0x4048e398b90ae1b6;
char* ptr = (char*) &l;
std::cout.write(ptr, 8);
std::cout.flush();
// for (int i = 0; i < 8; ++i)
// std::cout.put(ptr[i]);
// std::cout.flush()
}
Java应用程序:
public static void main(String[] argv) throws IOException {
Process p = Runtime.getRuntime().exec("prog.exe");
InputStream is = p.getInputStream();
for (int i = 0 ; i < 8; ++i) {
System.err.print(Long.toHexString(is.read()) + " ");
}
}
这些是非常简单的示例,但它们用于演示我的问题。当我在Windows 7机器上运行它时。我得到以下Java输出:
b6 e1 d a b9 98 e3 48
预期输出
b6 e1 a b9 98 e3 48 40
不知何故,插入了额外的0x0d字节。然而,真正奇怪的是,如果在java应用程序中我们再读取一个字节(将8更改为9),我们得到
b6 e1 d a b9 98 e3 48 40
这意味着InputStream实际上包含9个字节的数据,一旦删除了额外的0x0d,它就包含正确的数据。
你们觉得怎么样?正如我之前提到的,这不会经常发生,但是当它发生时,它是灾难性的。
提前致谢, zienkikk
答案 0 :(得分:6)
cout
在文本模式下打开,我想说的是0xa(换行)字符在输出预处理期间转换为<CRLF>
序列。
我认为不可能将二进制数据可靠地写入cout
(例如,参见here),因此我将所需的输出转换为文本,然后在输入端反序列化(爪哇)。
答案 1 :(得分:3)
C ++正在将0x0A(即\ n)转换为0x0d0a,即\ r \ n。有一种方法可以阻止它这样做,无法帮助你解决它的问题。我不会自己使用iostreams作为二进制数据,我可能只使用write()或fwrite()。
答案 2 :(得分:2)
在我看来,你的Windows shell将UNIX样式行终止符LF(0xA)转换为Windows行终结者CRLF(0xD OxA)。
通常,出于此特定原因,不建议将二进制数据写入程序输出流。将长数据转换为文本,然后在Java端解析它。