我正在编写服务器/客户端应用程序,服务器将与许多不同的客户端进行通信 . 与每个客户端的通信发生在运行服务器的机器上的单独线程中 . 到目前为止,我一直在使用BufferedReader类,以便使用readLine()方法从客户端套接字读取数据 . 我对readLine()的问题是它在找到换行符时会停止读取 . 由于我的程序的性质,我想用一个字符序列替换新的行限制,如$ ^%,所以使用readLine()调用BufferedReader将继续读取它找到的unitl&^% . 例如,如果客户端尝试发送url或文件路径,其中\ n可以作为自然路径的一部分找到,readLine()方法将读取\ n并停止进一步读取 .
我已经创建了以下类来尝试解决此问题 . 但我现在创造了一个更大的一个 . 当我使用BufferedReader类和readLine()方法时,我的服务器可以为很多客户端提供服务,但是当我使用CustomBufferedReader和readCustomLine()时,服务器在4或5个线程开始运行后崩溃 . 我很确定我的课程比readLine()消耗了大量资源,但我不知道,为什么或如何 .
我很感激有关此事的任何见解 .
public class CustomBufferedReader extends BufferedReader {
public CustomBufferedReader(Reader reader) {
super(reader);
}
/**
* Keeps reading data from a socket and stores them into a String buffer until
* the combination of $^% is red.
*
* @return A String containing the buffer red without the $^% ending.
* @throws IOException
*/
public String readCustomLine() throws IOException {
//$^%
String buffer="";
try
{
if(super.ready())
{
//First I'm reading 3 bytes in order to have at least 3 bytes
//in the buffer to compare them later on.
try
{
buffer = buffer + (char)super.read();
buffer = buffer + (char)super.read();
buffer = buffer + (char)super.read();
}
catch (IOException e)
{
e.printStackTrace();
System.out.println(e.getMessage());
}
int i=0;
//This while well keep reading bytes and adding the to the buffer until it reads
//$^% as the terminating sequence of bytes.
while (!(buffer.charAt(i)=='$' && buffer.charAt(i+1)=='^' && buffer.charAt(i+2)=='%')){
try
{
buffer = buffer + (char)super.read();
i++;
}
catch (IOException e)
{
e.printStackTrace();
System.out.println(e.getMessage());
}
}
// Returns the saved buffer after subtracting the $^% ending.
return buffer.substring(0, buffer.length() - 3);
}
}
catch (IOException e)
{
//e.printStackTrace();
}
return buffer;
}
}
1 回答
我认为这是一种更简单的方法来实现您的目标:
关于为什么readCustomLine的实现不起作用,您可能会遇到并发问题 . 如果你看一下BufferedReader的readLine实现,你可能会注意到它的所有代码都运行在 synchronized 块中 . 所以你可以在你的代码中尝试一下 .
此外,如果从super.read()抛出异常,您只需捕获它并继续运行,即使生成的缓冲区有错误,您也可以尝试删除内部的try / catch块 .
最后,正如EJP指出的那样,你应该删除ready()调用并检查每个super.read()是否为-1(意味着EOF) .