[英]Reading Lines and byte[] from input stream
我有一個網絡套接字,它接收以下類型的消息:(大約每秒24條)
EG命令: [Pos,1,2,3,4,1,2,3,4]\\n
圖片: [IMG,36000]\\nbyte[36000]
(byte [36000]是36000個字節的數組)
因此,我需要一個能夠讀取行和byte []的流的Reader。 問題在於,BufferedReader會轉換字符集,這對圖像非常非常非常有害,因此讀取字符串並將其轉換為字節似乎不是一種選擇。
我試圖將DataInputStreamReader和BufferedReader連接到流,但是在第一次更改閱讀器后,它似乎中斷了,但是我真的不確定是什么引起了那里的問題。
顯而易見的解決方案是:
char c;
String s = "";
do{
c= (char)read.read(); //maybe charset conversion here
s+=c;
}while(c!= "\n");
if(s.startsWith("[IMG")){
int len = Integer.parseInt(s.split(",")[1]);
byte[] img = new byte[len];
read.read(img);
...
但是我正在尋找一種更好的方法,我需要減少手動操作。
在最簡單的情況下,我可以編寫以下代碼:(實際上實際上不多於:D)
String s = read.readLine();
String[] parts = s.split(",");
if(parts[0].equals("[IMG")){
byte[] img = new byte[Integer.parseInt(parts[1])];
read.readByte(img);
...
更改視點可能會有所幫助:將其視為字節流,可以根據需要將其轉換為字符串。
在我的情況下,我有一個TCP客戶端/服務器對,該對必須處理包含多個ASCII控制字符的消息,包括CR和LF(在Windows上為Java“ newline”),並且所有內容都必須“按原樣”傳遞。
可以使用字符串來構建具有嵌入式控制代碼的消息,但是嵌入任何“換行符”(例如VT)意味着不能使用字符串發送或接收消息-解決方法是改為以字節為單位傳遞數據。
這是我所做的(在服務器和客戶端上)的本質:
// ASCII control codes
char SOH = (char) 0x01;
char STX = (char) 0x02;
char ETX = (char) 0x03;
String CRLF = "" + (char) 0x0D + (char) 0x0A;
int characterCount = 0;
String characterSet = "US-ASCII"; // "UTF-8", UTF-16", etc.
String incomingData = "";
String outgoingData = "";
ServerSocket servSock = new ServerSocket( servPort );
Socket clntSock = servSock.accept();
InputStream incomingData = clntSock.getInputStream();
OutputStream outgoingData = clntSock.getOutputStream();
while ( true )
{
characterCount = in.read( byteBuffer ); // blocks, waiting for remote machine
incomingData = new String( byteBuffer, characterSet ); // omit 2nd parameter to use default encoding
outgoingData = SOH + STX + "Whatever it is" + CRLF + CRLF + CRLF + "you need" + CRLF + "to do" + ETX;
byteBuffer = outgoingData.getBytes( CharacterSet );
out.write( byteBuffer );
}
遠端准確獲取發送的內容(38個字符):SOH + STX +“無論是什么” + CRLF + CRLF + CRLF +“您需要” + CRLF +“要做” + ETX
最后的想法:如果有一種方法/方法可以指定I / O包使用的“換行符”,則應該可以這樣:
// My first attempt was for a scanner that is functionally equivalent to System.out but
// automatically adjusts itself to the SYSTEM-DEPENDENT newline:
//
//String LineSeparator = System.getProperty( "line.separator" );
//String MessageSeparator = Pattern.quote( LineSeparator );
//Pattern EndOfMessageRegEx = Pattern.compile( MessageSeparator );
String MessageEndsWith = "" + STX + ETX; // Change this to whatever you need
String MessageSeparator = Pattern.quote( MessageEndsWith );
Pattern EndOfMessageRegEx = Pattern.compile( MessageSeparator );
ServerSocket thisMachine = new ServerSocket( portNumber );
Socket otherMachine = thisMachine.accept();
PrintWriter messageToClient = new PrintWriter( otherMachine.getOutputStream(), true );
BufferedReader messageFromClient = new BufferedReader(
new DataInputStreamReader( otherMachine.getInputStream(),
CharacterEncoding ) );
Scanner ReceivedData = new Scanner( messageFromClient ).useDelimiter( EndOfMessageRegEx );
首先使用InputStream將所有數據接受為二進制數據。
InputStream stream = ...
然后在識別文本時閱讀:
int b = stream.read();
if (b == (byte)'E') { // Text stream recognized.
BufferedReader reader = new BufferedReader(
new InputStreamReader(stream, charset));
... use read no longer stream
}
您可以在已經讀取過的InputStream上創建一個Reader。 對於控件,您可能會使用單獨的方法和try-with-resources。 BufferedInputStream可能將原始InputStream包裝為二進制數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.