【问题标题】:ByteArrayInputStream cannot read long with ByteArrayOutputStream written in JavaByteArrayInputStream 无法用 Java 编写的 ByteArrayOutputStream 读取长
【发布时间】:2022-10-14 21:29:25
【问题描述】:

我有一个长数字的读取代码,如下所示;

ByteArrayInputStream in;
public long readUInt64() throws IOException {
    return readUInt16() | readUInt16() << 16L | readUInt16() << 32L | readUInt16() << 48L;

public int readUInt16() throws IOException {
    return readWithEOF() | readWithEOF() << 8;
}
    int readWithEOF() throws IOException {
    int data = this.in.read();
    if (data < 0)
        throw new EOFException();
    return data;
}

我有如下写文件;

ByteArrayOutputStream baos;
public void writeUInt64(Long val) {
        
    writeUInt16((int) (val >> 0L));
    writeUInt16((int) (val >> 16L));
    writeUInt16((int) (val >> 32L));
    writeUInt16((int) (val >> 48L));    
}
public void writeUInt16(int num) {      
    baos.write(num >> 0);
    baos.write(num >> 8);
}

当我尝试存储像 253402300799999L 这样的大值时,读取结果完全不同。对于小值,代码运行良好。 假设无法更改读取代码,我该如何解决此问题。 提前致谢。

【问题讨论】:

  • 我试过 boas.write(num & 0xff) 但仍然返回 -769654785
  • 检查所有“(int)(val >> 0L)”你是否得到一个整数溢出并创建一个负数?

标签: java


【解决方案1】:

您的阅读代码不正确。

您需要在班次前将int 转换为long (&lt;&lt;)。

return readUInt16() 
    | ((long)readUInt16()) << 16L 
    | ((long)readUInt16()) << 32L 
    | ((long)readUInt16()) << 48L;

因此,如果您无法更改读取的代码,就不可能解决您的问题。

【讨论】:

    【解决方案2】:

    看起来转换为 int 会导致溢出尝试:

    writeUInt16((int) ( (val >> 0L) & 0xffffL) );
    

    您需要对所有 4 个 16 位写入执行此操作。

    【讨论】:

    • 尝试但仍然读取 -769654785 结果
    • @sea1731 我犯了同样的错误。您需要在转换为 int 之前执行 &。我想我修好了。
    猜你喜欢
    • 2016-06-01
    • 1970-01-01
    • 2016-03-22
    • 2018-03-20
    • 2020-03-11
    • 2016-10-31
    • 2020-02-26
    • 1970-01-01
    • 2010-09-09
    相关资源
    最近更新 更多