[英]data transfer not working using ObjectOutputStream.writeObject()
I created a android to pc client-server app, and throughout my app's other features i use ObjectOutputStream.writeObject(AbstractPacket object) to send controls and data b/w my apps and they all works fine, now when i tried to send a file(eg:a small jpg/png file), after sending the file bytes to the server side and recreating the original jpg file, the file is showing that its corrupted and is not displaying, but its size is exact same as sent from the client android app. 我创建了一个android pc pc客户端服务器应用程序,并且在我的应用程序的其他功能中,我都使用ObjectOutputStream.writeObject(AbstractPacket对象)发送控件和数据到我的应用程序中,并且当我尝试发送文件时,它们都可以正常工作(例如:一个小的jpg / png文件),在将文件字节发送到服务器端并重新创建原始的jpg文件后,该文件显示其已损坏且未显示,但其大小与从客户端发送的完全相同android应用。 here's some code,
这是一些代码,
client side:(file to bytearray) 客户端:(文件到字节数组)
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
String filename= myFile.getName();
FileTransferPacket packet = new FileTransferPacket(mybytearray,mybytearray.length,filename);
TCPconnection.sendPacket(packet);
FileTransferPacket extends the AbstractPacket: FileTransferPacket扩展了AbstractPacket:
public class FileTransferPacket extends AbstractPacket implements Serializable {
byte[] bytes;
long size;
String filename;
public FileTransferPacket(byte[] bytes,long size,String filename) {
super(Protocol.Command.FILE_TRANSFER);
this.bytes = bytes;
this.size = size;
this.filename = filename;
}
public byte[] getBytes() {
return bytes;
}
public long getSize() {return size; }
public String getFilename() {return filename; }
}
Here's how i send the packet object to the server: 这是我将数据包对象发送到服务器的方法:
public void sendPacket(AbstractPacket packet) throws IOException {
connectionOutput.writeObject(packet);
connectionOutput.flush();
connectionOutput.reset();
}
At the server side I read the objects like: 在服务器端,我读取如下对象:
AbstractPacket packet = (AbstractPacket) connectionInput.readObject(); AbstractPacket封包=(AbstractPacket)connectionInput.readObject();
receiver.handleReceiveData(packet, connection); receiver.handleReceiveData(数据包,连接);
public synchronized void handleReceiveData(AbstractPacket packet, TcpConnection connection) {
String filename=packet.getFilename();
long size= packet.getSize();
byte [] mybytearray = new byte [(int)size];
byte[] myByteArray=packet.getBytes();
String userHomeFolder = System.getProperty("user.home");
userHomeFolder+="\\Desktop\\"+filename;
try {
FileOutputStream fos = new FileOutputStream(userHomeFolder);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(mybytearray, 0 , (int)size);
bos.flush();
fos.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Can somebody tell me what's actually wrong here, also please suggest how to fix them. 有人可以告诉我这里到底有什么问题吗,也请提出解决方法。
After some searching, i did found that maybe i can fix if i used normal OutputStreams to send only the file's bytearray to server, it could work: 经过一番搜索,我确实发现,如果我使用正常的OutputStreams仅将文件的字节数组发送到服务器,也许可以修复,它可以工作:
outputStream.write(mybytearray, 0, mybytearray.length); outputStream.write(mybytearray,0,mybytearray.length);
But in my whole app i used ObjectoutputStream, so how can i include both types of streams on a single socket, also on server side how can i distinguish the incoming data as an Object/bytesbuffer. 但是在我的整个应用程序中,我使用了ObjectoutputStream,因此如何在单个套接字上包括两种类型的流,在服务器端又如何将传入的数据区分为对象/字节缓冲区。
You can add control bytes to indicate the type of stream. 您可以添加控制字节以指示流的类型。 Here's example code how it works.
这是示例代码,其工作方式。
It's bit tricky. 有点棘手。 If possible using different port number would be more simple.
如果可能,使用其他端口号会更简单。
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// File stream.
FileOutputStream fos = new FileOutputStream("test1.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
// add controll bytes.
bos.write(0);
bos.write("file contents".getBytes());
bos.close();
// Object stream.
FileOutputStream fos2 = new FileOutputStream("test2.txt");
// add controll bytes.
fos2.write(1);
ObjectOutputStream oos = new ObjectOutputStream(fos2);
Exception serializableObj = new RuntimeException("serialize test");
oos.writeObject(serializableObj);
oos.close();
readStream(new FileInputStream("test1.txt"));
readStream(new FileInputStream("test2.txt"));
}
private static void readStream(InputStream in) throws IOException, ClassNotFoundException {
int controll = in.read();
if (controll == 0) { // File stream
BufferedInputStream bis = new BufferedInputStream(in);
FileOutputStream fos = new FileOutputStream("test3.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] buff = new byte[1024];
while (true) {
int ret = bis.read(buff);
if (ret < 0) {
break;
}
bos.write(buff, 0, ret);
}
in.close();
bos.close();
BufferedReader br = new BufferedReader(new FileReader("test3.txt"));
String line = br.readLine();
System.out.println("line: " + line);
assert (line.equals("file contents"));
br.close();
} else if (controll == 1) { // Object stream
ObjectInputStream ois = new ObjectInputStream(in);
RuntimeException e = (RuntimeException)ois.readObject();
assert (e instanceof RuntimeException);
assert (e.getMessage().equals("serialize test"));
System.out.println("message: " + e.getMessage());
ois.close();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.