【问题标题】:Java StreamCorruptedException when sending object containing byte data over a certain size发送包含超过一定大小的字节数据的对象时出现 Java StreamCorruptedException
【发布时间】:2015-10-14 13:32:58
【问题描述】:

我有一个 Java 客户端-服务器(使用 ocsf,如果这里有人知道的话)我用来将文件从客户端上传到服务器的基础设施。客户端实际上是一个 Android 应用程序(不确定在这种情况下是否重要)

我这样做是通过读取文件数据(字节),将其包装在一个包含一些其他详细信息(用户 ID 等)的对象中,然后通过 ObjectOutputStream 将此对象发送到服务器。

似乎一切正常,直到文件的字节数组超过一定大小(尚不确定这个奇怪的阈值是多少,但似乎 645KB 已经太多了)。然后,服务器在尝试从ObjectInputStream 读取对象时抛出StreamCorruptedException 并关闭套接字。

包含文件字节的对象消息的代码:

public class MessageUploadFile extends MessageToServer {

private static final long serialVersionUID = 2356276507283427913L;
private String _destId;
private TransferDetails _td;
private byte[] _fileData;


public MessageUploadFile(String srcId, TransferDetails td, byte[] fileData){
    super(srcId);
    _destId = td.getDestinationId();
    _td = td;
    _fileData = fileData;

}

客户端套接字和流初始化:

 clientSocket= new Socket(host, port);
 output = new ObjectOutputStream(clientSocket.getOutputStream());
 input = new ObjectInputStream(clientSocket.getInputStream());

使用以下方式发送消息:

 output.writeObject(msg);  

这些是服务器端的流初始化:

 input = new ObjectInputStream(clientSocket.getInputStream());
 output = new ObjectOutputStream(clientSocket.getOutputStream());

阅读消息使用:

 msg = input.readObject();

【问题讨论】:

  • @ravindra 感谢您的回复。问题是我没有使用也不能使用 DataOutputStream。我发送一个对象是有原因的(所以我可以将上传详细信息与数据一起发送)。你说这是不可能的吗?如果是这样,我如何将此元数据与文件数据本身相关联?我考虑过使用单独的套接字并在其上使用 DataStreams,但关联元数据的问题仍然存在......
  • 我总是发送字节数组并重新构造它
  • 所以你说的是基本上将 OutputStream 包装在 ByteArrayOutputStream 中,并用 ObjectOutputStream 包装所有这些>?如果是这样,我应该只在客户端还是在客户端和服务器端都这样做?

标签: java android sockets client


【解决方案1】:
StreamCorruptedException

反序列化数据时可以抛出 Java StreamCorruptedException。它基本上发生在以下两种主要情况之一:

您尝试围绕一些实际上并未使用ObjectOutputStream 写入的数据打开ObjectInputStream

readObject() 操作期间,流进入“错误的位置”。

来自java docs

当从对象流中读取的控制信息违反内部一致性检查时引发。

但是我得到了这个带有大消息的异常并转移到字节数组解决方案。

看看这篇文章:http://www.javamex.com/tutorials/io/StreamCorruptedException.shtml

总之,将 Object 与字节数组相互转换并重新创建它

【讨论】:

  • 刚从这个找到解释:stackoverflow.com/questions/2393179/…
  • 感谢您的帮助!我真的很想采用您的解决方案。我的问题是我觉得某些东西仍然不是最佳实践,因为我认为您应该始终能够向用户显示文件上传的进度条,并且只需将整个对象与文件数据字节数组一起转换并发送批量不允许这样做。还是觉得我错过了什么。
  • 我仍然认为您可以根据字节数组大小显示进度条。 byte[] 到 Object 的转换可能不需要更长的时间,但下载字节数组需要时间。
  • 感谢您的帮助!我最终所做的是最初发送一个指示上传详细信息的对象(文件大小、发件人 ID 等),然后在服务器端抓取 ObjectInputStream 中的下划线 inputStream 并分别传输文件的字节。完成后,客户端和服务器继续通过对象进行通信。它现在工作正常。谢谢!
【解决方案2】:

我最终所做的是最初发送一个指示上传详细信息的对象(文件大小、发件人 ID 等),然后在服务器端抓取 ObjectInputStream 中的下划线 inputStream 并分别传输文件的字节.完成后,客户端和服务器继续通过对象进行通信。目前可以正常使用。

希望这对某人有所帮助。

【讨论】:

    猜你喜欢
    • 2013-03-21
    • 2021-04-06
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多