2011-06-16 103 views
1

我從發送一個UTF8字符串從一個c套接字到java套接字有一些麻煩。 下面的方法正常工作:DataInputStream和readLine()與UTF8

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8")); 
main.title = in.readLine(); 

但後來我需要一個int java.io.InputStream.read(byte[] b, int offset, int length)方法,該方法不適合一個BufferedReader存在。於是我試圖採取一個DataInputStream

DataInputStream in2 = new DataInputStream(socket.getInputStream()); 

,但一切都記載只是垃圾。

然後我試圖使用DataInputStreamreadLine()方法,但是這並沒有給我正確的UTF8字符串。

你看到我的困境。我不能爲一個InputStream使用兩個閱讀器嗎?或者我可以轉換DataInputStream.readLine()結果並將其轉換爲UTF8?

感謝, 馬丁

+6

我是否正確地理解您正在同一個「對話」中同時發送文本和二進制數據?爲相同的輸入流創建兩個閱讀器應該沒有問題。問題是知道何時(以及多少)閱讀哪個閱讀器。由於您有混合類型的數據,因此它們在您讀取基礎數據流時都會消耗(並提前)底層數據流。你可以只讀字節流,然後在代碼中明確地轉換字節(new String(bytes,「UTF-8」)等)。或者你可以將你的通信分成兩個不同的套接字。 – pap 2011-06-16 11:11:40

+2

@pap:這是非常值得的答案;-) – 2011-06-16 11:19:08

+0

@pap:我同意,發表評論作爲答案:) – helios 2011-06-16 11:50:23

回答

7

我們從design of the UTF-8 encoding知道值0x0A的唯一用法是LINE FEED('\n')。因此,你可以閱讀,直到你打吧:

/** Reads UTF-8 character data; lines are terminated with '\n' */ 
    public static String readLine(InputStream in) throws IOException { 
    ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 
    while (true) { 
     int b = in.read(); 
     if (b < 0) { 
     throw new IOException("Data truncated"); 
     } 
     if (b == 0x0A) { 
     break; 
     } 
     buffer.write(b); 
    } 
    return new String(buffer.toByteArray(), "UTF-8"); 
    } 

我做你的協議使用\n作爲行終止的假設。如果沒有 - 好的,指出你寫的約束通常是有用的。

+0

很好!這就是我需要的!感謝大家! – martin 2011-06-16 16:21:31

1

我認爲你不應該不匹配BufferedReaderDataInputStream這裏。 DataInputStream也有readLine(),所以請使用它。 又一個評論。我不確定這是一個問題,但要避免多次撥打socket.getInputStream()。做一次,然後用其他流和閱讀器來包裝它。

+0

我試圖從DataInputStream使用readLine()方法,但後來我沒有得到正確的unicode跡象。文檔說這個方法已被廢棄:http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataInputStream.html#readLine%28%29。所以現在我已經帶着兩個閱讀器 inputStream = socket.getInputStream(); dataInputStream = new DataInputStream(inputStream);新的BufferedReader(new InputStreamReader(inputStream,「UTF8」)); – martin 2011-06-16 12:53:02

+0

首先,bufferedReader讀取一些文本。然後dataInputStream必須讀取一些字節,但它會卡住,而read()方法返回-1,儘管我發送的字節數多於dataInputStream接收到的字節數。緩衝讀取器是否消耗一些字節? oO – martin 2011-06-16 12:55:03

1

我是否正確地理解,您正在同一個「對話」中的同一套接字上發送文本和二進制數據?爲相同的輸入流創建兩個閱讀器應該沒有問題。問題是知道何時(以及多少)閱讀哪個閱讀器。由於您有混合類型的數據,因此它們在您讀取基礎數據流時都會消耗(並提前)底層數據流。你可以只讀字節流,然後在代碼中明確地轉換字節(new String(bytes,「UTF-8」)等)。或者你可以將你的通信分成兩個不同的套接字。

3

請問不是在同一個InputStream上使用BufferedReader和DataInputStream !!我這樣做了,花了好幾天的時間試圖弄清楚爲什麼我的代碼破裂了。 BufferedReader讀取的內容可能超過了從緩衝區中提取的內容,從而導致DataInputStream在「BufferedReader」中的數據被讀取。這導致數據丟失,導致我的程序「掛起」等待它到達。