我試圖從默認字符編碼爲UTF-8的服務器向默認字符編碼爲的客戶端發送一個字符串windows-1252通過套接字和PrintWriter。PrintWriter over Socket OutputStream導致數據損壞/丟失
當我運行下面的客戶端時,儘管我嘗試使用CharsetDecoder來轉換字符串,但我並沒有收到141的原始值。
作爲一個控制測試,我已經嘗試在Eclipse中運行這兩個類,並強制通過下面的對話使用UTF-8作爲默認編碼系統 - 並且我觀察到當兩個客戶端都使用UTF -8,輸出在客戶端被成功解釋。
更新:它看起來像我能夠流字節和恢復初始格式,但爲了這樣做,我必須知道在服務器上使用的編碼。在這種情況下沒有某種圖書館會有用嗎?我寧願不會被迫以字節數組的形式傳輸數據。
服務器:
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
//Runs on a server with default character encoding of UTF-8
public class TestServer {
public static void main(String[] args) throws Exception {
PrintWriter writer = null;
ServerSocket serverSocket = null;
try {
int x = 141;
String s = "#" + (char)x;
serverSocket = new ServerSocket(5555);
Socket clientSocket = serverSocket.accept();
writer = new PrintWriter(
(new OutputStreamWriter(clientSocket.getOutputStream())), true);
System.out.println((int)s.charAt(1));
writer.write(s);
} catch(Exception e) {
e.printStackTrace();
} finally {
writer.close();
serverSocket.close();
}
}
}
客戶:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
//Runs on a server with default character encoding of windows-1252
public class TestClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket("localhost", 5555);
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
String string = reader.readLine();
System.out.println((int)string.charAt(1)); //prints 194 when it was 141 on the other end
//Charset.defaultCharset returns windows-1252
CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
CharBuffer buffer = decoder.decode(ByteBuffer.wrap(string.getBytes()));
String convertedString = buffer.toString();
System.out.println((int)convertedString.charAt(1)); //still prints 194
String convertedString2 = new String(string.getBytes(), "UTF-8");
System.out.println((int)convertedString2.charAt(1)); //prints 65533 ??
s.close();
}
}
嗯..我看到了作爲一個選項,但我真的想避免。是否還有其他更高級別的OutputStream實現可以使用? – kwikness
我認爲它實際上使用byte []方法的代碼實際上稍少一些。查看我提供的代碼示例。 – mttdbrd
謝謝。我猜這會起作用,但是你的解決方案不提供在客戶端不知道服務器字符編碼的情況下解碼的方法。另外,我真的很喜歡不需要讀/寫字節的解決方案。 – kwikness