`
gengu
  • 浏览: 84976 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

java IO学习笔记[2]

 
阅读更多

 

我昨天在写java网络编程的时候想到这样几个问题,现在总结一下。

 

一:TCP编程是面向字节流的

      我用socket编程,是基于TCP/IP的,而TCP协议是传输层的协议,它是面向连接的,与UDP很大的不同在于前者是面向字节流的协议,而后者是用户数据报协议(User Datagram Protocol ),面向字节流有一个很大的好处,那就是可以进行拥塞控制,进行流量控制,进行差错控制。

       为什么UDP不行呢?是因为UDP应用层给传输层什么数据报,传输层就发送什么数据报,根本不管它有多少个字节,传输太多是不是会造成阻塞。而TCP就不一样了,应用层让传输层传输数据的时候,传输层并不会直接发送,而是从缓冲区一个字节一个字节的拿出来,TCP发送端是有发送窗口的,这个窗口就是TCP进行流量控制,差错控制的核心。而接收端又是有接收窗口的,总之通过窗口直接的滑动(或者快了,或者顺序乱了,或者帧丢失了),来进行以上的控制。

       那么java在进行socket编程的时候只能使用字节流了?答案并不是这样

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStream;

public class Server1 {
/**服务器端*/
	public static void main(String[] args) throws IOException{
		ServerSocket ss = new ServerSocket(5678);
		
		Socket socket = ss.accept();
		
		PrintWriter out = new PrintWriter(socket.getOutputStream());
		
		BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));  
		
		while(true)
		{
			String str=in.readLine();  
			System.out.println(str);
			out.println("hello world");
			out.flush();
			
		}
	}
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * socket编程的客户端
 * */
public class Client1 
public static void main(String[] args)throws Exception{  
	Socket server=new Socket("localhost",5678);  
	BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));  
	PrintWriter out=new PrintWriter(server.getOutputStream());  
	BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));  
	while(true){  
		String str=wt.readLine();  
		out.println(str);  
		out.flush();  
		if(str.equals("end")){  
			break;  
			}  
		System.out.println(in.readLine());  
		}  
	server.close();  
	}  
}

以上的代码给人一种使用了面向字符流的假象,其实我们可以看到这里的字符流其实是对字节流进行了封装,这里应该是适配器模式,把一个字节流转化成了一个字符流 ,server.getInputStream()方法的源码是,可以看到它实际返回的是字节流。

public InputStream getInputStream() throws IOException

 

二:print和println的区别到底是什么

 

在socket编程中,如果使用PrintWriter类作为输出流,那么为什么一定要println(String str),而不是print()。

       在我的印象中println只是在print的后面加上一个换行符,估计大部分人跟我的想法一样,可是,看了一下源码发现

/**
     * Prints a String and then terminate the line.  This method behaves as
     * though it invokes <code>{@link #print(String)}</code> and then
     * <code>{@link #println()}</code>.
     *
     * @param x  The <code>String</code> to be printed.
     */
    public void println(String x) {
	synchronized (this) {
	    print(x);
	    newLine();
	}
    }

 public void print(String s) {
	if (s == null) {
	    s = "null";
	}
	write(s);
    }

 

 从上面的两个方法至少可以看到两点1:println方法是线程安全的:2:多了一个newLine()方法。

那么newLine()是个什么方法呢?

   /**
    private BufferedWriter textOut;
    */
	
	private void newLine() {
	try {
	    synchronized (this) {
		ensureOpen();
		textOut.newLine();
		//在BufferedWriter类中 newLine方法只是写一个换行符
		 /**
		 * Writes a line separator.  The line separator string is defined by the
		 * system property <tt>line.separator</tt>, and is not necessarily a single
		 * newline ('\n') character.
		 *
		 * @exception  IOException  If an I/O error occurs
		 *
			 public void newLine() throws IOException {
			 write(lineSeparator);
			 }
		*/
		/**
		 * Flushes the output buffer to the underlying character stream, without
		 * flushing the stream itself.  This method is non-private only so that it
		 * may be invoked by PrintStream.
		   这里的意思是说刷新输出流到存在下面的字符流,而不需要刷新这个流本身
		   
        */
		textOut.flushBuffer();
		/*
		   那么这里到底做了什么呢?
		*/
		charOut.flushBuffer();
		if (autoFlush)
		    out.flush();
	    }
	}
	catch (InterruptedIOException x) {
	    Thread.currentThread().interrupt();
	}
	catch (IOException x) {
	    trouble = true;
	}
    }

  也就是说println方法比print做的事情多得多。它有终止改行,刷新缓冲区的功能,而print却没有,当使用print输出的时候,没有刷新,也没有终止,而只是单独的写入进去。

 

那么,刷新一个缓冲区到底在底层是做了什么呢。

 

 

 

 

分享到:
评论

相关推荐

    Java IO学习笔记+代码

    Java IO学习笔记+代码,全面介绍IO中的方法、类,很适合初学者

    java IO流学习笔记

    java IO流学习笔记

    java学习笔记1(java io/nio)

    java学习笔记1(java io/nio)设计模式

    java李兴华学习笔记之Java_IO操作

    收集的java李兴华老师的课件笔记。感觉还不错,适合回顾和新手补习。

    java io流学习笔记1

    NULL 博文链接:https://lpf.iteye.com/blog/1471932

    Java学习笔记7.0

    《Java JDK6学习笔记》是作者良葛格本人近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型...

    Java学习笔记-IO篇

    这是我自己整理的Java学习笔记,希望对大家有帮助

    io流的学习笔记

    io流学习笔记,主要适合入门的人士学习及观看

    java学习笔记之Java-IO操作共19页.pdf.zi

    java学习笔记之Java_IO操作共19页.pdf.zip

    java学习笔记

    java学习笔记大全:java内容介绍 java编程可以分成三个方向: 1、java se (j2se)桌面开发 java中的基础中的基础 2、java ee (j2ee)web开发 3、java me (j2me)手机开发 java se课程介绍 java面向对象编程(基础) java...

    IO-黑马程序员Java学习笔记.rar

    IO—黑马程序员Java学习笔记.rar

    java IO流详解

    文档是关于JAVA常用IO流的学习笔记,可以用于参考,学习。

    IO笔记.zip关于javaIO流部分的详细笔记

    这是关于java各个IO流,从节点流到装饰缓冲流的一系列笔记纲要,帮助更好的理解和学习java的IO流

    java笔记.zip

    尚硅谷康师傅java学习笔记。 、2020-4-5 java学习笔记 2020-4-6 java笔记 ---内部类 2020-4-6 java笔记 ---异常 2020-4-6 java笔记 --多线程 2020-4-8 java笔记 String类 2020-4-9 java 比较器 2020-4-10 java笔记 ...

    java-IO流与异常机制学习笔记

    自己总结,知识点全面,包含了,IO流,异常机制等学习笔记 含有代码实例可供参考,需要mybase打开 持续更新,需要的自行下载 附上本人写的学习博客 https://blog.csdn.net/qq_35577787/article/details/105088073

    Java学习笔记之IO流

    详细介绍了IO的用法,基本实现原理,并介绍了序列化与反序列化的实现方法。谢谢

    javaIO流.xmind

    自己总结的java中IO流的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合java的爱好者和学习者

Global site tag (gtag.js) - Google Analytics