java socket 文件传输 乱码问题

时间:2022-03-19 16:23:20
我的发送端:
try {
     ServerSocket serverSocket = new ServerSocket(6870);
     while(true) {
Socket socket = serverSocket.accept();
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
iFile = (gmit.File) inputStream.readObject();
oFile = new File("C:\\myFile.txt");
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream("C:\myFile.txt")));
DataOutputStream ps = new DataOutputStream(socket.getOutputStream());
         ps.writeUTF(oFile.getName());
         ps.flush();
         int bufferSize = 8192;
         byte[] buf = new byte[bufferSize];
         while (true) {
               int read = 0;
               if (fis != null) {
                   read = fis.read(buf);
               }
               if (read == -1) {
                   break;
               }
               ps.write(buf, 0, read);
          }
          ps.flush();                
          fis.close();
          socket.close();                
     }
} catch (Exception e) {
e.printStackTrace();
}
接收端:
try {
File file = new File("download");
if(!file.exists()) {
     file.mkdir();
}
Socket socket = new Socket(friend.getIp(), 6870);
int bufferSize = 8192;
         byte[] buf = new byte[bufferSize];
         DataInputStream diStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
         String savePath = "download\\" + diStream.readUTF();
         DataOutputStream doStream = new DataOutputStream(new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream(savePath))));
         while(true) {
             int read = 0;
             if (diStream != null) {
              read = diStream.read(buf);
             }
             if (read == -1) {
                 break;
             }
             doStream.write(buf, 0, read);
         }
         doStream.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
我用上面的程序传输文件,doc文件和txt文件,无论中英文都会出现乱码,传输pdf文件正常,应该怎么处理呢?

8 个解决方案

#1


DataInputStream

public class DataOutputStream extends FilterOutputStreamimplements DataOutput

A data output stream lets an application write primitive Java data types to an output stream in a portable way. An application can then use a data input stream to read the data back in. 


用InputStream和OutputStream不可以吗?
为啥要用DataOutputStream 和 DataInputStream?传输的根本就不是java里面的具体类型

#2


InputStream和OutputStream,是面向二进制数(byte数组)操作的两个类。
DataInputStream和DataOutputStream是面向Java数据操作的两个类。
楼主要传输文件内容,最好只用InputStream和OutputStream,
不要用DataInputStream和DataOutputStream。
楼主的问题就出在DataInputStream和DataOutputStream上面,
使用这两个类,会在每次写入操作的时候,追写一个间隔符数据,
读取的时候,以间隔符数据,分割写入时的数据,
而针对二进制数据的写入读取,就会忽略间隔符数据,
间隔符与没有间隔符的数据混合发送,致使接收端数据定位不准确,
产生了乱码问题。

楼主使用DataInputStream和DataOutputStream两个类,无非就是想把文件名传过去。
同样可以使用二进制的形式进行文件名的传输啊,
先将文件名转换成byte数组,
然后,发送byte数组的长度,长度数据占4个字节,整型数据,
最后,发送byte数据。
接收端,先接收4个字节的数据,转换成整数,就知道文件名所占二进制字节流的长度。
然后,按照长度接收数据,将数据转成字符串,即为文件名。

#3


oFile = new File("C:\\myFile.txt");
应该是你读出来的数据本来就是乱码 注意文件的编码格式  用utf-8或者gbk编码 和你的源代码编码格式保持一致

#4


应该用InputStream和OutputStream,这相当于文件复制传输,底层只能说二进制才能复制翻译,不然会出现乱码。去尝试一下也区别一下

#5


使用二进制就是了 
用writeUTF貌似会进行编码,会改变二进制数据 

#6


如果再不行,可以试试先把字符串打成ISO-8859-1,再用UTF-8拼好.new String(str.getByte("ISO-8859-1"),"UTF-8");试一下吧。

#7


应该是这个错误。

#8


谢谢大家的帮助,问题已经解决了,是因为DataOutputStream和DataInputStream传输完毕后没有关闭的问题,在发送端加上ps.close(),接收端加上diStream.close()就好了。

#1


DataInputStream

public class DataOutputStream extends FilterOutputStreamimplements DataOutput

A data output stream lets an application write primitive Java data types to an output stream in a portable way. An application can then use a data input stream to read the data back in. 


用InputStream和OutputStream不可以吗?
为啥要用DataOutputStream 和 DataInputStream?传输的根本就不是java里面的具体类型

#2


InputStream和OutputStream,是面向二进制数(byte数组)操作的两个类。
DataInputStream和DataOutputStream是面向Java数据操作的两个类。
楼主要传输文件内容,最好只用InputStream和OutputStream,
不要用DataInputStream和DataOutputStream。
楼主的问题就出在DataInputStream和DataOutputStream上面,
使用这两个类,会在每次写入操作的时候,追写一个间隔符数据,
读取的时候,以间隔符数据,分割写入时的数据,
而针对二进制数据的写入读取,就会忽略间隔符数据,
间隔符与没有间隔符的数据混合发送,致使接收端数据定位不准确,
产生了乱码问题。

楼主使用DataInputStream和DataOutputStream两个类,无非就是想把文件名传过去。
同样可以使用二进制的形式进行文件名的传输啊,
先将文件名转换成byte数组,
然后,发送byte数组的长度,长度数据占4个字节,整型数据,
最后,发送byte数据。
接收端,先接收4个字节的数据,转换成整数,就知道文件名所占二进制字节流的长度。
然后,按照长度接收数据,将数据转成字符串,即为文件名。

#3


oFile = new File("C:\\myFile.txt");
应该是你读出来的数据本来就是乱码 注意文件的编码格式  用utf-8或者gbk编码 和你的源代码编码格式保持一致

#4


应该用InputStream和OutputStream,这相当于文件复制传输,底层只能说二进制才能复制翻译,不然会出现乱码。去尝试一下也区别一下

#5


使用二进制就是了 
用writeUTF貌似会进行编码,会改变二进制数据 

#6


如果再不行,可以试试先把字符串打成ISO-8859-1,再用UTF-8拼好.new String(str.getByte("ISO-8859-1"),"UTF-8");试一下吧。

#7


应该是这个错误。

#8


谢谢大家的帮助,问题已经解决了,是因为DataOutputStream和DataInputStream传输完毕后没有关闭的问题,在发送端加上ps.close(),接收端加上diStream.close()就好了。