PrintWriter应用实例

希望您在看这篇博客之前,知道Java IO技术,至少写过IO操作的Demo!

另外建议您看看: Java IO:IO流中的flush方法

这篇博客,主要使用Socket实例(很简单的小例子)来引出问题,然后在探讨问题。

1. Socket服务端

[java] view plain copy print ?
  1. package mark.zhang;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.InputStream;  
  5. import java.io.InputStreamReader;  
  6. import java.net.ServerSocket;  
  7. import java.net.Socket;  
  8.   
  9. public class Server {  
  10.   
  11.     public static void main(String[] args) throws Exception {  
  12.         ServerSocket server = new ServerSocket(3000);  
  13.         Socket socket = server.accept();  
  14.         InputStream is = socket.getInputStream();  
  15.         BufferedReader br = new BufferedReader(new InputStreamReader(is));  
  16.         String info = br.readLine();  
  17.         System.out.println("server receive info: " + info);  
  18.     }  
  19.   
  20. }  
2. Socket客户端

[java] view plain copy print ?
  1. package mark.zhang;  
  2.   
  3. import java.io.OutputStream;  
  4. import java.io.PrintWriter;  
  5. import java.net.Socket;  
  6.   
  7. public class Client {  
  8.     public static void main(String[] args) throws Exception {  
  9.         Socket client = new Socket("127.0.0.1"3000);  
  10.         OutputStream os = client.getOutputStream();  
  11.         PrintWriter pw = new PrintWriter(os, true);  
  12.         pw.print("Hello,Server");  
  13.         pw.close();  
  14.         // pw.println("Hello,Server");   
  15.     }  
  16. }  
代码很简单,主要是客户端向服务端发送一个字符串,服务端将接收到的信息打印出来。

上面代码,运行(先运行Server.java后运行Client.java)之后,一切正常!

经过Debug,我发现,调用层次:

PrintWriter的 close()方法 ---> BufferedWriter的close()方法 ---> OutputStreamWriter的close()方法 ---> StreamEncoder的close()方法

BufferedWriter的close()方法源码:

[java] view plain copy print ?
  1. public void close() throws IOException {  
  2.     synchronized (lock) {  
  3.         if (out == null) {  
  4.         return;  
  5.         }  
  6.         try {  
  7.             flushBuffer();  
  8.         } finally {  
  9.             out.close();  
  10.             out = null;  
  11.             cb = null;  
  12.         }  
  13.     }  
OutputStreamWriter的close()方法源码:
[java] view plain copy print ?
  1. public void close() throws IOException {  
  2.     se.close();  
  3. }  
StreamEncoder的close()方法源码可以参看 http://blog.csdn.net/androidbluetooth/article/details/6460726这篇文章的代码。

那么,我们做点调整,改变这些正常反应吧!修改客户端代码(注释掉pw.close()):

[java] view plain copy print ?
  1. package mark.zhang;  
  2.   
  3. import java.io.OutputStream;  
  4. import java.io.PrintWriter;  
  5. import java.net.Socket;  
  6.   
  7. public class Client {  
  8.     public static void main(String[] args) throws Exception {  
  9.         Socket client = new Socket("127.0.0.1"3000);  
  10.         OutputStream os = client.getOutputStream();  
  11.         PrintWriter pw = new PrintWriter(os, true);  
  12.         pw.print("Hello,Server");  
  13.         // pw.close();   
  14.         // pw.println("Hello,Server");   
  15.     }  
  16. }  
服务端打印结果:

[java] view plain copy print ?
  1. server receive info: null  
也就是说,没有接收到任何信息。也就是说,这种方式在服务端无法接收到信息。

恶作剧一把之后,我们再次修改代码,如下:

[java] view plain copy print ?
  1. package mark.zhang;  
  2.   
  3. import java.io.OutputStream;  
  4. import java.io.PrintWriter;  
  5. import java.net.Socket;  
  6.   
  7. public class Client {  
  8.     public static void main(String[] args) throws Exception {  
  9.         Socket client = new Socket("127.0.0.1"3000);  
  10.         OutputStream os = client.getOutputStream();  
  11.         PrintWriter pw = new PrintWriter(os, true);  
  12.         //pw.print("Hello,Server");   
  13.         //pw.close();   
  14.         pw.println("Hello,Server");  
  15.     }  
  16. }  
ok,服务端可以接收到信息。看看PrintWriter类的println方法源码:

[java] view plain copy print ?
  1. public void println(String x) {  
  2.     synchronized (lock) {  
  3.         print(x);  
  4.         println();  
  5. }  
[java] view plain copy print ?
  1. public void print(String s) {  
  2.     if (s == null) {  
  3.         s = "null";  
  4.     }  
  5.     write(s);  
  6. }  
[java] view plain copy print ?
  1. public void println() {  
  2.     newLine();  
  3. }  
newLine()就是加入一个回车符:

[java] view plain copy print ?
  1. private void newLine() {  
  2.     try {  
  3.         synchronized (lock) {  
  4.         ensureOpen();  
  5.         out.write(lineSeparator);  
  6.         if (autoFlush)  
  7.             out.flush();  
  8.         }  
  9.     }  
  10.     catch (InterruptedIOException x) {  
  11.         Thread.currentThread().interrupt();  
  12.     }  
  13.     catch (IOException x) {  
  14.         trouble = true;  
  15.     }  
  16.     }  
lineSeparator定义:
[java] view plain copy print ?
  1. lineSeparator = (String) java.security.AccessController.doPrivileged(  
  2.                new sun.security.action.GetPropertyAction("line.separator"));  
服务端的readLine()方法,遇到回车符就读一次数据(一行一行的读)。所以服务端可以收到信息。

3. 研究一下readLine

再次修改Client.java代码:

[java] view plain copy print ?
  1. package mark.zhang;  
  2.   
  3. import java.io.DataOutputStream;  
  4. import java.io.OutputStream;  
  5. import java.net.Socket;  
  6.   
  7. public class Client {  
  8.     public static void main(String[] args) throws Exception {  
  9.         Socket client = new Socket("127.0.0.1"3000);  
  10.         OutputStream os = client.getOutputStream();  
  11.         DataOutputStream dos = new DataOutputStream(os);  
  12.         dos.writeBytes("Hello,Server1");  
  13.         dos.writeBytes("\n");  
  14.         dos.writeBytes("Hello,Server2");  
  15.         //dos.close();   
  16.     }  
  17. }  
服务端接收信息:

[java] view plain copy print ?
  1. server receive info: Hello,Server1  
说明,没有接收到Hello,Server2。这就说明,readLine遇到回车就算读完信息。

关于readLine()方法的其它用法,见下代码:

[java] view plain copy print ?
  1. package csdn.zhwx;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.BufferedWriter;  
  5. import java.io.File;  
  6. import java.io.FileInputStream;  
  7. import java.io.FileOutputStream;  
  8. import java.io.IOException;  
  9. import java.io.InputStreamReader;  
  10. import java.io.OutputStreamWriter;  
  11. import java.nio.charset.Charset;  
  12.   
  13. public class BufferedReaderTest {  
  14.   
  15.     public static void getFile(String readFilePath, String readFileName,  
  16.             String writeFilePath, String writeFileName) {  
  17.         File reaFile = null;  
  18.         FileInputStream fis = null;  
  19.         BufferedReader bReader = null;  
  20.   
  21.         File writeFile = null;  
  22.         FileOutputStream fos = null;  
  23.         BufferedWriter bWriter = null;  
  24.   
  25.         try {  
  26.             if (!(readFileName == null || readFileName.length() <= 0)) {  
  27.                 reaFile = new File(readFilePath + readFileName);  
  28.                 fis = new FileInputStream(reaFile);  
  29.                 // bReader = new BufferedReader(new InputStreamReader(fis,"GBK"));//指定GBK编码,一般用在汉化windows上。   
  30.                 // bReader = new BufferedReader(new InputStreamReader(fis));//默认编码,和系统编码一致。linux为UTF-8   
  31.                 bReader = new BufferedReader(  
  32.                         new InputStreamReader(fis, "UTF-8"));// 指定UTF-8编码   
  33.   
  34.                 writeFile = new File(writeFilePath, writeFileName);  
  35.                 fos = new FileOutputStream(writeFile);  
  36.                 // bWriter = new BufferedWriter(new OutputStreamWriter(fos));//默认编码,和系统编码一致。linux为UTF-8   
  37.                 bWriter = new BufferedWriter(new OutputStreamWriter(fos,  
  38.                         "UTF-8"));// 指定UTF-8编码   
  39.   
  40.                 String str = null;  
  41.                 while ((str = bReader.readLine()) != null) {// 该方法不会将读取到的换行\n写到文件中   
  42.                     // System.out.println(str);   
  43.                     // 要自己手动加\n   
  44.                     bWriter.write(str + "\n");  
  45.                       
  46.                     /*bWriter.write(str); 
  47.                     bWriter.newLine();*/  
  48.                       
  49.                     // 不刷新的话,文件不会有内容   
  50.                     bWriter.flush();  
  51.                 }  
  52.             }  
  53.   
  54.         } catch (Exception e) {  
  55.             e.printStackTrace();  
  56.             try {  
  57.                 fis.close();  
  58.                 bReader.close();  
  59.                 fos.close();  
  60.                 bWriter.close();  
  61.             } catch (IOException e1) {  
  62.                 e1.printStackTrace();  
  63.             }  
  64.         } finally {  
  65.             try {  
  66.                 fis.close();  
  67.                 bReader.close();  
  68.                 fos.close();  
  69.                 bWriter.close();  
  70.             } catch (IOException e1) {  
  71.                 e1.printStackTrace();  
  72.             }  
  73.         }  
  74.     }  
  75.   
  76.     public static void main(String[] args) {  
  77.         getFile("/home/zhihui/Downloads/""hello.txt",  
  78.                 "/home/zhihui/Downloads/""copyFormHello.txt");  
  79.           
  80.         //linux下测试   
  81.         /*当前JRE:1.6.0_23 
  82.         当前JVM的默认字符集:UTF-8*/  
  83.         System.out.println("当前JRE:" + System.getProperty("java.version"));  
  84.         System.out.println("当前JVM的默认字符集:" + Charset.defaultCharset());   
  85.     }  

你可能感兴趣的:(java,exception,server,String,socket,newline)