json传二进制文件(转)
前几天,项目中需要在socket中传输二进制文件.
这本来是很简单的事,因为我们知道socket传输的就是字节流.所以非常简单.
java的实现:
Java代码
import ;
import .InputStream;
import ;
import ;
public class FileReceive {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8800);
("server started!");
while (true) {
Socket socket = ();
InputStream inputStream = ();
FileOutputStream fileOutputStream = new FileOutputStream("d:/");
int i;
while ((i = ()) != -1) {
(i);
}
();
();
();
();
break;
}
}
}
import ;
import .OutputStream;
import ;
public class FileSend {
public static void main(String[] args) throws Exception {
// 打开文件流
FileInputStream fileInputStream = new FileInputStream("d:/");
Socket socket = new Socket("127.0.0.1", 8800);
OutputStream outputStream = ();
int i;
// 读取并写入socket
while ((i = ()) != -1) {
(i);
}
// 结束
();
();
}
}
import ;
import ;
import ;
import ;
public class FileReceive {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8800);
("server started!");
while (true) {
Socket socket = ();
InputStream inputStream = ();
FileOutputStream fileOutputStream = new FileOutputStream("d:/");
int i;
while ((i = ()) != -1) {
(i);
}
();
();
();
();
break;
}
}
}
import ;
import ;
import ;
public class FileSend {
public static void main(String[] args) throws Exception {
// 打开文件流
FileInputStream fileInputStream = new FileInputStream("d:/");
Socket socket = new Socket("127.0.0.1", 8800);
OutputStream outputStream = ();
int i;
// 读取并写入socket
while ((i = ()) != -1) {
(i);
}
// 结束
();
();
}
}
测试的时候先运行FileReceive,再运行FileSend
这样你就能看到在D:/下有一个文件是"".跟原来的一模一样.代表传输成功!
不过我们的项目有个要求,需要用json的协议来传输.
我们都知道json是文本格式.所以我马上想到的是把文件编码成文本,再进行传输.
所以关键就是要把一个二进制文件翻译成文本,再翻译回去.如果可以,也就代表这个方案是可行的.
马上我就写出了第一个版本:
Java代码
// 读取文件
FileInputStream fileInputStream = new FileInputStream("d:/");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
while ((i = ()) != -1) {
(i);
}
();
// 把文件存在一个字节数组中
byte[] filea = ();
();
String fileaString = new String(filea);
(fileaString);
// 写入文件
FileOutputStream fileOutputStream = new FileOutputStream("d:/");
(());
();
();
// 读取文件
FileInputStream fileInputStream = new FileInputStream("d:/");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
while ((i = ()) != -1) {
(i);
}
();
// 把文件存在一个字节数组中
byte[] filea = ();
();
String fileaString = new String(filea);
(fileaString);
// 写入文件
FileOutputStream fileOutputStream = new FileOutputStream("d:/");
(());
();
();
发现根本无法打开,很是奇怪?而且大小也不一样了.
检查代码后发现把数组转化成string的时候后面还可以加个参数charset[编码名称].
于是马上改了一下:
.......
String fileaString = new String(filea,"uft-8");
.......
(("utf-8"));
结果还是不行,又改了一下:
.......
String fileaString = new String(filea,"ISO-8859-1");
.......
(("ISO-8859-1"));
结果成功了.
结合以前的编码知识,总算是想明白了.
把字节数组转换成字符串时,如果charset为空,那就表示用你的默认编码进行转换.
而不管gb2312和utf8都不是用单字节表示一个字符的.只要他不认识的,他就会默认转换成一个特定字符,所以这样的转换是不可逆的.
只有像ascii这样的单字节编码的转换才是可逆的.
明白了这个道理.我们就可以用json协议来传任何的数据了.^_^,大功告成!
有关编码的问题我推荐阮一峰的一篇博文,对字符编码有很好的解释.
/blog/2007/10/ascii_unicode_and_utf