我创建了一个Android到PC的客户端 - 服务器应用程序,在我的应用程序的其他功能中,我使用ObjectOutputStream.writeObject(AbstractPacket对象)来发送控件和数据我/我的应用程序,它们一切正常,现在当我尝试发送文件(例如:一个小的jpg / png文件),在将文件字节发送到服务器端并重新创建原始jpg文件后,该文件显示其已损坏且未显示,但其大小为与客户端Android应用程序发送的完全相同。 这里有一些代码,
客户端:(文件到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扩展了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; }
}
这是我如何将数据包对象发送到服务器:
public void sendPacket(AbstractPacket packet) throws IOException {
connectionOutput.writeObject(packet);
connectionOutput.flush();
connectionOutput.reset();
}
在服务器端,我读取了如下对象:
AbstractPacket packet =(AbstractPacket)connectionInput.readObject();
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();
}
}
有人可以告诉我这里究竟有什么问题,还请建议如何修复它们。
经过一番搜索后,我确实发现如果我使用普通的OutputStreams只将文件的bytearray发送到服务器,我可以解决它,它可以工作:
outputStream.write(mybytearray,0,mybytearray.length);
但是在我的整个应用程序中我使用了ObjectoutputStream,那么如何在单个套接字上包含这两种类型的流,同样在服务器端如何将传入的数据区分为Object / bytesbuffer。
答案 0 :(得分:1)
您可以添加控制字节以指示流的类型。 以下是示例代码的工作原理。
这有点棘手。 如果可能,使用不同的端口号会更简单。
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();
}
}
}