使用outputstream发送文件长度,使用inputstream接收长度和字节[],用于从一个设备到另一个Android/Java设备的流帧
我搜索了又搜索,我所发现的一切都很有用,但我不断地发现一个内存不足的错误。我发送的图像是.06 MB,因此我知道问题不是将字节[]解码为位图。当我移除while循环时,这就像一帧的魅力一样,但我想要多帧。我得到一个字节[],并使用套接字将其发送到另一个设备,但我不知道如何做到这一点。我的问题是,我没有发送和接收正确的字节[]长度。这就是我目前正在做的事情使用outputstream发送文件长度,使用inputstream接收长度和字节[],用于从一个设备到另一个Android/Java设备的流帧,java,android,sockets,inputstream,outputstream,Java,Android,Sockets,Inputstream,Outputstream,我搜索了又搜索,我所发现的一切都很有用,但我不断地发现一个内存不足的错误。我发送的图像是.06 MB,因此我知道问题不是将字节[]解码为位图。当我移除while循环时,这就像一帧的魅力一样,但我想要多帧。我得到一个字节[],并使用套接字将其发送到另一个设备,但我不知道如何做到这一点。我的问题是,我没有发送和接收正确的字节[]长度。这就是我目前正在做的事情 while (count != -1) { //first send the byte[] length dataOut
while (count != -1) {
//first send the byte[] length
dataOutputStream.writeInt(sendPackage.length);
//pass a byte array
publishProgress("sending file to client");
showMyToastOnUiThread(String.valueOf(sendPackage.length));
outputStream.write(sendPackage, 0, sendPackage.length);
outputStream.flush();
}
在不同设备上接收字节[]:
int count = inputStream.read();
while (count != -1) {
int byteArrayLength = dataInputStream.readInt();
Log.i(MainActivity.TAG, "Starting convert to byte array");
byte[] receivedBytes = convertInputStreamToByteArray(inputStream, byteArrayLength);
Bitmap bitmap = BitmapFactory.decodeByteArray(receivedBytes, 0, receivedBytes.length);
publishProgress(bitmap);
}
//convert inputstream to byte[]
public byte[] convertInputStreamToByteArray(InputStream inputStream, int readLength) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] data = new byte[readLength];
try {
Log.i(MainActivity.TAG, "Starting convert to byte array while loop");
int readTotal = 0;
int count = 0;
while (count >= 0 && readTotal < readLength) {
count = inputStream.read(data, readTotal, readLength - readTotal);
if (readLength > 0) {
readTotal += count;
}
}
Log.i(MainActivity.TAG, "Finished convert to byte array while loop");
} catch (IOException e) {
Log.e(MainActivity.TAG, "error: " + e.getMessage());
e.printStackTrace();
}
return data;
}
int count=inputStream.read();
而(计数!=-1){
int byteArrayLength=dataInputStream.readInt();
Log.i(MainActivity.TAG,“开始转换为字节数组”);
byte[]receivedBytes=将inputStream转换为ByteArray(inputStream,byteArrayLength);
位图位图=位图工厂.decodeByteArray(接收字节,0,接收字节.length);
出版进度(位图);
}
//将inputstream转换为字节[]
公共字节[]convertInputStreamToByteArray(InputStream InputStream,int readLength){
ByteArrayOutputStream bos=新建ByteArrayOutputStream();
字节[]数据=新字节[readLength];
试一试{
i(MainActivity.TAG,“在循环时开始转换为字节数组”);
int readTotal=0;
整数计数=0;
而(计数>=0&&readTotal0){
readTotal+=计数;
}
}
Log.i(MainActivity.TAG,“在循环时完成了到字节数组的转换”);
}捕获(IOE异常){
Log.e(MainActivity.TAG,“错误:+e.getMessage());
e、 printStackTrace();
}
返回数据;
}
这就是问题所在:
int count = inputStream.read();
while (count != -1) {
您正在消耗一个字节,然后忽略它。这意味着您读取的下一个值(大小)将不正确。你需要一种不同的方式来判断你是否在这条河的尽头。一些选择:
- 完成后发送-1;这样,只要
返回-1,您就可以立即停止readInt
- 如果您知道,请在开始发送之前发送要发送的图像数
- 如果流支持标记,请使用
,然后使用标记(1)
,然后使用读取()
。我不知道会不会。如果没有,您可以将其包装在重置()
中BufferedInputStream
- 重新实现
您自己的方式,将流的结尾检测为预期的可能性,而不是引发异常DataInputStream.readInt
- 只需在
中捕获一个异常(不太好-到达流的末尾并不是真正的异常)readInt
count
永远不会改变吗?接收端从读取单个字节开始:int count=inputStream.read()编码>然后在计数时循环!=-1.但是这个字节不是由发送方发送的,循环中的计数也不会改变。@MichaelButscher我在一个异步任务(一个线程)中完成我的所有工作,而将某些内容发布到ui线程并保持异步任务运行的方法是publishProgress()。它调用一个推送到ui线程的方法。@JBNizet我想读入具有特定长度的字节[]s,直到套接字断开连接为止。我该怎么做?我希望图像在插座打开时发送。当发送图像的套接字关闭时,readInt将为-1,对吗?我看到计数没有被重置,但当试图检测文件的结尾时,这应该无关紧要,是吗?@user305223:不,当套接字关闭时,readInt
将抛出一个IOException
。好的,我删除了inputstream.read(),它就工作了。现在,由于bitmapfactory.decodebytearray()的原因,我的内存在大约一秒钟内就用完了。谢谢您的帮助。@user305223:我会添加诊断来检查您是否分配了正确的大小-但是如果是,可能是因为您没有足够的内存来存储所有这些图像。这是因为我的内存不足。这是一个我可以在java中释放内存的错误。。。垃圾收集不够快。