本文介绍了从输入流读取行和字节[]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我有一个网络套接字接收以下类型的消息:(每秒约24个) 命令EG: [Pos,1,2,3,4,1,2,3,4] \\\ 图片: [IMG,36000] \\\byte [36000] (byte [36000]是一个36000字节的数组) 所以我需要一个读取器来读取行和byte []。问题是,BufferedReader转换字符集,这是非常,非常非常糟糕的图像,所以读取字符串并将其转换为字节似乎不是一个选项。 我试图连接一个DataInputStreamReader和BufferedReader到流,但它似乎在读者第一次更改后中断,但我不确定是什么导致的问题。 显而易见的解决方案是: char c; String s =; do { c =(char)read.read(); //也许charset转换在这里 s + = c; } while(c!=\\\); if(s.startsWith([IMG)){ int len = Integer.parseInt(s.split(,)[1]); byte [] img = new byte [len]; read.read(img); ... 但我正在寻找一个更好的, 处理这个问题的建议方法是什么? 是否有一种方式将两个或多个读取器连接到输入流? 是否有可读取byte []和字符串的读取器? 将所有内容写入byte []并从中读取? (我怎么知道,什么时候停止阅读?) 我可以防止将字节[]混乱的chartype转换吗? (我可以使用缓冲读取器) 在最简单的情况下,我可以写这个代码: 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); ... 解决方案 help:将它看作一个字节流,根据需要转换为字符串。 在我的例子中,我有一个TCP客户端/服务器对,必须处理包含几个ASCII控制字符的消息,包括CR& LF(=在Windows上的java换行符) - 一切都必须通过按原样。 字符串可以用于构建具有嵌入控制代码的消息,但嵌入任何换行字符(例如VT)意味着字符串不能用于发送或接收message - 解决方法是将数据作为字节传递。 它是我做的(在服务器和客户端)的本质: // ASCII控制代码 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等。 String incomingData =; String outgoingData =; ServerSocket servSock = new ServerSocket ); Socket clntSock = servSock.accept(); InputStream incomingData = clntSock.getInputStream(); OutputStream outgoingData = clntSock.getOutputStream(); while(true) { characterCount = in.read(byteBuffer); //块,等待远程机器 incomingData = new String(byteBuffer,characterSet) ; //忽略第二个参数使用默认编码 outgoingData = SOH + STX +无论是什么+ CRLF + CRLF + CRLF +你需要+ CRLF + byteBuffer = outgoingData.getBytes(CharacterSet); out.write(byteBuffer); } pre> 远端获取发送的内容(38个字符):SOH + STX +无论是什么+ CRLF + CRLF + CRLF + CRLF +to do+ ETX 最后一想:如果有一个方法/方法来指定I / O包使用的newline应该是可能的: //我的第一次尝试是一个功能等同于System.out的扫描器, //自动调整到SYSTEM-DEPENDENT换行符: // // String LineSeparator = System.getProperty(line.separator); // String MessageSeparator = Pattern.quote(LineSeparator); // Pattern EndOfMessageRegEx = Pattern.compile(MessageSeparator); String MessageEndsWith =+ STX + ETX; //将它改为任何你想要的东西 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); I have a network socket which recieves the following types of messages: (about 24 per second)Commands EG: [Pos,1,2,3,4,1,2,3,4]\nImages: [IMG,36000]\nbyte[36000] (byte[36000] is an array of 36000 bytes)So I would need an Reader for that stream that is able to read lines and byte[]. The problem is, that the BufferedReader converts the charset, which is very, very, very bad for images, so reading a string and converting it to byte seems not to be an option.I tried to connect a DataInputStreamReader and a BufferedReader to the stream but it seems to break after the first change of the reader, but I am not really sure about what caused the problem there.The obvious solution is: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); ...But I am searching for a better one where I need to do less manually.What is the recommended way to deal with this problem?Is there a wayto connect two or more readers to an input stream?Is there a reader which can read byte[] and strings?Is it probably easier to write everything to byte[] and read from that? (How do I know then, when to stop reading?)Can I prevent the chartype conversion which messes the byte[] up? (Then i could use the Buffered Reader)In the easiest case I could write that code: (Which is actually not much more :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); ... 解决方案 Changing the viewpoint can help: Look at it as a byte stream that gets converted to strings as needed.In my case I have a TCP client/server pair that must handle messages containing several ASCII control characters including CR & LF (= the java "newline" on Windows) - and everything must be passed through "as is".A string can be used to build a message with embedded control codes but embedding any "newline" character (e.g. VT) means that a string cannot be used send or receive the message - the workaround is to pass the data as bytes instead.Heres the essence of what I did (on server and client) :// ASCII control codeschar 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 );}The far end gets exactly what was sent (38 characters): SOH + STX + "Whatever it is" + CRLF + CRLF + CRLF + "you need" + CRLF + "to do" + ETXA final thought : If there was a way/method to specify the "newline" used by the I/O packages something like this should be possible:// 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 needString 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 ); 这篇关于从输入流读取行和字节[]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!