json傳二進制文件(轉)


json傳二進制文件(轉)
 
前幾天,項目中需要在socket中傳輸二進制文件. 
這本來是很簡單的事,因為我們知道socket傳輸的就是字節流.所以非常簡單. 
java的實現: 
Java代碼 
import java.io.FileOutputStream;   
import java.io.InputStream;   
import java.net.ServerSocket;   
import java.net.Socket;   
  
public class FileReceive {   
  
    public static void main(String[] args) throws Exception {   
        ServerSocket serverSocket = new ServerSocket(8800);   
        System.out.println("server started!");   
        while (true) {   
            Socket socket = serverSocket.accept();   
            InputStream inputStream = socket.getInputStream();   
            FileOutputStream fileOutputStream = new FileOutputStream("d:/b.png");   
            int i;   
            while ((i = inputStream.read()) != -1) {   
                fileOutputStream.write(i);   
            }   
            fileOutputStream.flush();   
            fileOutputStream.close();   
            inputStream.close();   
            serverSocket.close();   
            break;   
        }   
    }   
  
}   
  
  
  
  
import java.io.FileInputStream;   
import java.io.OutputStream;   
import java.net.Socket;   
  
public class FileSend {   
  
    public static void main(String[] args) throws Exception {   
        // 打開文件流   
        FileInputStream fileInputStream = new FileInputStream("d:/a.png");   
        Socket socket = new Socket("127.0.0.1", 8800);   
        OutputStream outputStream = socket.getOutputStream();   
        int i;   
        // 讀取並寫入socket   
        while ((i = fileInputStream.read()) != -1) {   
            outputStream.write(i);   
  
        }   
        // 結束   
        outputStream.flush();   
        socket.close();   
    }   
  
}  
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class FileReceive {

	public static void main(String[] args) throws Exception {
		ServerSocket serverSocket = new ServerSocket(8800);
		System.out.println("server started!");
		while (true) {
			Socket socket = serverSocket.accept();
			InputStream inputStream = socket.getInputStream();
			FileOutputStream fileOutputStream = new FileOutputStream("d:/b.png");
			int i;
			while ((i = inputStream.read()) != -1) {
				fileOutputStream.write(i);
			}
			fileOutputStream.flush();
			fileOutputStream.close();
			inputStream.close();
			serverSocket.close();
			break;
		}
	}

}




import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.Socket;

public class FileSend {

	public static void main(String[] args) throws Exception {
		// 打開文件流
		FileInputStream fileInputStream = new FileInputStream("d:/a.png");
		Socket socket = new Socket("127.0.0.1", 8800);
		OutputStream outputStream = socket.getOutputStream();
		int i;
		// 讀取並寫入socket
		while ((i = fileInputStream.read()) != -1) {
			outputStream.write(i);

		}
		// 結束
		outputStream.flush();
		socket.close();
	}

}

測試的時候先運行FileReceive,再運行FileSend 
這樣你就能看到在D:/下有一個文件是"b.png".跟原來的一模一樣.代表傳輸成功! 
不過我們的項目有個要求,需要用json的協議來傳輸. 
我們都知道json是文本格式.所以我馬上想到的是把文件編碼成文本,再進行傳輸. 
所以關鍵就是要把一個二進制文件翻譯成文本,再翻譯回去.如果可以,也就代表這個方案是可行的. 
馬上我就寫出了第一個版本: 
Java代碼 
// 讀取文件   
FileInputStream fileInputStream = new FileInputStream("d:/a.png");   
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();   
int i;   
while ((i = fileInputStream.read()) != -1) {   
    byteArrayOutputStream.write(i);   
}   
fileInputStream.close();   
// 把文件存在一個字節數組中   
byte[] filea = byteArrayOutputStream.toByteArray();   
byteArrayOutputStream.close();   
  
String fileaString = new String(filea);   
System.out.println(fileaString);   
// 寫入文件   
FileOutputStream fileOutputStream = new FileOutputStream("d:/b.png");   
fileOutputStream.write(fileaString.getBytes());   
fileOutputStream.flush();   
fileOutputStream.close();  
		// 讀取文件
		FileInputStream fileInputStream = new FileInputStream("d:/a.png");
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		int i;
		while ((i = fileInputStream.read()) != -1) {
			byteArrayOutputStream.write(i);
		}
		fileInputStream.close();
		// 把文件存在一個字節數組中
		byte[] filea = byteArrayOutputStream.toByteArray();
		byteArrayOutputStream.close();

		String fileaString = new String(filea);
		System.out.println(fileaString);
		// 寫入文件
		FileOutputStream fileOutputStream = new FileOutputStream("d:/b.png");
		fileOutputStream.write(fileaString.getBytes());
		fileOutputStream.flush();
		fileOutputStream.close();

發現b.png根本無法打開,很是奇怪?而且大小也不一樣了. 
檢查代碼后發現把數組轉化成string的時候后面還可以加個參數charset[編碼名稱].
於是馬上改了一下: 
....... 
String fileaString = new String(filea,"uft-8"); 
....... 
fileOutputStream.write(fileaString.getBytes("utf-8")); 
結果還是不行,又改了一下: 
....... 
String fileaString = new String(filea,"ISO-8859-1"); 
....... 
fileOutputStream.write(fileaString.getBytes("ISO-8859-1")); 
結果成功了. 
結合以前的編碼知識,總算是想明白了. 
把字節數組轉換成字符串時,如果charset為空,那就表示用你的默認編碼進行轉換. 
而不管gb2312和utf8都不是用單字節表示一個字符的.只要他不認識的,他就會默認轉換成一個特定字符,所以這樣的轉換是不可逆的. 
只有像ascii這樣的單字節編碼的轉換才是可逆的. 
明白了這個道理.我們就可以用json協議來傳任何的數據了.^_^,大功告成! 
有關編碼的問題我推薦阮一峰的一篇博文,對字符編碼有很好的解釋. 
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM