PrintWriter类的println()和writer()方法的一点区别

PrintWriter类的println(String x)方法和writer(Stirng x)方法都表示把输入写到输出流中,但需要注意println()方法会再文本的后面加上分隔符,如windows下为“\r\n”,不同操作系统间有区别。println(String x)的实现在源码中为:

public void println(String x) {
    synchronized (lock) {
        print(x);
        println();
    }
}
其中,println()的源码实现为: newLine();对该方法继续分析发现其实现中包含以下代码: out .write( lineSeparator );也就是向输出流中写入一个lineSeparator,继续深入探寻lineSeparator发现该属性在类PrintWriter的构造方法中被赋值为:

lineSeparator = java.security.AccessController.doPrivileged(
    new sun.security.action.GetPropertyAction("line.separator"));
可见该属性与系统相关。
writer(String x)方法的最终实现为: out.write(buf, off, len);
其中buf为字符数组,默认大小为1024,当字符串的长度大于1024时,

将使用字符串的长度作为数组容量,该方法将字符串分解成一个个字符然后写入输出流中,

不会写入分隔符。

综上,当服务器端输出流使用writer(String x)方法时,客户端使用Scanner类的hasNextLine()方法和nextLine()方法从输入流中读取数据时,由于nextLine()方法无法读取到行分隔符,该方法将造成阻塞,客户端将不会显示服务器端发来的信息,解决方法:当使用write(String x)时,在字符串后面加上行分隔符“\r\n”,或者使用println(Stirng x)方法。
public class ServerHalfClosed {
    public static void main(String[] args) {
        try(ServerSocket serverSocket = new ServerSocket(9000)){
            Socket server = null;
            try {
                server = serverSocket.accept();
                Scanner sc = new Scanner(System.in);
                PrintWriter pw = new PrintWriter(server.getOutputStream());
                String line=null;
                while ((sc.hasNextLine() && !(line = sc.nextLine()).trim().equals("over"))){
                    pw.write(line+"\r\n");
                    //pw.println(line);也可以这样
            pw.flush();
                }
                pw.write(line);
                pw.flush();
                server.shutdownOutput();
                pw.close();
            } finally {
                if(server!=null)
                server.close();
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 以上为服务器端代码。 
 
public class ClientHalfClosed {
    public static void main(String[] args) {
        try{
            Socket client =new Socket("localhost",9000);
            Scanner scan = new Scanner(client.getInputStream());
            PrintWriter pw = new PrintWriter(client.getOutputStream());
            System.out.println("客户端连接上:"+client.getLocalPort());
            pw.flush();
            client.shutdownOutput();
            String line=null;
            while (scan.hasNextLine()){
                if(!(line=scan.nextLine()).trim().equals("over"))
                    System.out.println("客户端收到:"+line+"来自服务端:"+client.getInetAddress().getHostAddress());
            }
            System.out.println("客户端收到:"+line+" ,接收完毕!");
            client.shutdownInput();
            pw.close();
            client.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
以上 为客户端代码。

 


  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值