PrintWriter中的print()和println()

今天在学习socket通信的时候,写了一个简单的Demo,运行的时候出现了一个问题,客户端在写入数据并调用flush方法后,服务器端并没有接收到数据。
客户端主要代码如下:

            Socket socket = new Socket(ipAddress, 2017);
            BufferedReader inReader = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            PrintWriter writer = new PrintWriter(socket.getOutputStream());
            BufferedReader systemReader = new BufferedReader(
                    new InputStreamReader(System.in));
            String inputText = systemReader.readLine();
            while (!inputText.equals("over")) {

                mCommonPrint.print("Client:" + inputText);
                writer.print(inputText);
                writer.flush();
                mCommonPrint.print("Server:" + inReader.readLine());
                inputText = systemReader.readLine();
            }
            writer.close();
            systemReader.close();
            inReader.close();
            socket.close();

服务器端主要代码如下:

            BufferedReader inReader = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            mCommonPrint.print("Clinet:" + inReader.readLine());
            PrintWriter writer = new PrintWriter(socket.getOutputStream());
            BufferedReader systemReader = new BufferedReader(
                    new InputStreamReader(System.in));
            String inputText = systemReader.readLine();
            while (!inputText.equals("over")) {
                writer.print(inputText);
                writer.flush();
                mCommonPrint.print("Server:" + inputText);
                mCommonPrint.print("Clinet:" + inReader.readLine());
                inputText = systemReader.readLine();
            }
            systemReader.close();
            writer.close();
            inReader.close();
            socket.close();
            serverSocket.close();

在网上查的资料都说是没有调用PrintWriter的flush()方法,但是我明明调用了。。。。
我试了一下如果直接在writer.print()后调用writer.close()方法,那么服务器端是可以获取到数据的。。。
但是依然木有解决问题。。。
最后仔细的看了看别人写的代码,发现问题了。。。
其他网友调用的是writer.println()方法,而我调用的是writer.print()方法,于是我换成了writer.println()方法,结果问题解决了!

但是为什么呢?
于是看了一下源码。。。
print()方法源码:
public void print(String s) {
if (s == null) {
s = “null”;
}
write(s);
}

println()方法源码:

 public void println(String x) {
        synchronized (lock) {
            print(x);
            println();
        }
    }
其中的println()调用了newLine():
private void newLine() {
        try {
            synchronized (lock) {
                ensureOpen();
                out.write(lineSeparator);
                if (autoFlush)
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }

从源码中可以看出,print()方法和write()方法没有太大的区别,println()方法中多了一个out.write(lineSeparator);添加了一个分隔符,并且可以设置自动flush,因为默认的autoFlush=false,可以在创建PrintWriter时设置为true。

PrintWriter writer = new PrintWriter(socket.getOutputStream(),true);

由此看来,是这个分隔符的原因。。。
然后发现了这句代码:

inReader.readLine()

readLine()是一行一行读取数据,而标识一行的方式就是使用分隔符。

官方说明:

Reads a line of text. A line is considered to be terminated by any one of a line feed (‘\n’), a carriage return (‘\r’), or a carriage return followed immediately by a linefeed

也就是说是如果没有遇到换行或者回车的分隔符,就会一直读取数据。
但是print()和write()方法中并没有添加分隔符,所以就出现了刚才的问题。

解决办法:
1.将writer.println(inputText);改为writer.println(inputText+“\n”);手动添加分隔符。
2.使用println()方法。
但是不管使用哪种方法都要调用flush()方法。

你可能感兴趣的:(Java)