2017-02-25 68 views
0

我正在尝试创建一个简单的java服务器应用程序,但我正在努力正确读取用BufferedReader的用户输入。 问题是行分隔符只是CR LF(“\ r \ n”) - 所以我不能使用readLine()标准方法。因此,我试图实现自己的方法:如何用BufferedReader读取CR LF行?

private String readCRLFLine(BufferedReader in) { 

    StringBuilder result = new StringBuilder(); 
    char cr = 'a'; // initialize cr 
    char lf; 

    try { 
     while (((lf = (char) in.read()) != '\n') && (cr != '\r')) { 
      cr = lf; 
      result.append(lf); 
     } 
     result.deleteCharAt(result.length() - 1); // delete \r from the result 
    } catch (IOException ex) { 
     // handle the exception here 
    } 

    return result.toString(); 
} 

现在,当我试图让打印出结果:

while ((userMessage = readCRLFLine(inputStream)) != null) { 
     System.out.println(userMessage); 
     break; 
} 

...只打印的字符序列的第一个破发(“\ r”或“\ n”),其余的输入通过方法 的第二次调用readCRLFLine(inputStream)读取 - 应该已经读取其他输入。

我希望能够处理像输入:

“ABC \ RABC \ n \ r \ ABC \ r \ n” 个

在这种情况下userMessage应该是:

“ABC \ RABC \ n \ r \ ABC”

我不能使用扫描仪和它的“useDeli米(“\ r \ n”)“方法,因为我需要设置TIMEOUT与”clientSocket.setSoTimeout(TIMEOUT)“和我所知道的,这是扫描仪不可能的。

我的“readCRLFLine”方法有什么问题?这个问题还有其他解决方案吗?

任何帮助,将不胜感激。

+3

是什么让你觉得BufferedReader.readLine()不支持CRLF?它的确如此。另外,无论您是使用Scanner还是其他类读取Socket InputStream,都不会改变设置套接字超时的能力。 –

+0

来自javadoc for BufferedReader.readLine():“一行被认为是由换行符('\ n'),回车符('\ r')或回车后跟一个回车符换行“。我的行只能由“\ r \ n” - >分隔,因此“\ n”和“\ r”不应被视为换行符。 – Filco28

+0

@ Filco28所以如果一行中有一个单独的'\ n'或'\ r',那么你希望它被认为是一行。注意:大多数文本编辑器都会尊重这一点,所以您所描述的不是普通的文本文件。 –

回答

1

您的方法不正确,因为while条件不是您实际需要的条件。

它说:“只要当前读取字符不是\n前一个字符比\r不同不同,请继续阅读”。

但这意味着当您阅读\n时,该条件为false,因为lf != '\n'为false。所以它会停止在第一个\n。它也将停止在\r之后的任何字符,因为然后cr != '\r'将会是false使得组合条件为假。

当前字符为\n且前一个字符为\r时,您希望停止循环。这意味着你的条件应该是! (lf == '\n' && cr == '\r')

现在注意德摩尔定律:“不(A和B)”相当于“不是A 不是B”。你错误地决定使用AND而不是OR。更改条件:

while (((lf = (char) in.read()) != '\n') || (cr != '\r')) { 
    ... 
} 

顺便说一句,你应该检查你将它转换为char之前比较一下你in读出的值不为负。负值表示客户端关闭了连接,如果发生这种情况,您将进入无限循环。

+0

是的,当然“&&”是问题。不知道为什么我错过了它。感谢您的帮助。我将在转换之前检查该值。 – Filco28