Java I/O流学习笔记(一)

一、流的概念

  1. 在计算机中,流是个抽象的概念,是对输入输出设备的抽象。在Java程序中,对于数据的输入输出操作,都以“流”的方式进行
  2. 流具有方向性,可以分为输入和输出。
  3. 以java程序本身作为参照点,如果数据是从程序“流向”文件,那么这个流就是输出流,如果数据是从文件“流向”程序,那么这个流就是输入流。例如:
    在这里插入图片描述
    注意,这里是以文件进行举例,java程序中还可以把数据写入到网络中、内存中等

二、流的分类

根据数据的流向分为:输入流和输出流

  • 输入流:把数据从其他设备上读到程序中的流
  • 输出流:把数据从程序中写出到其他设备上的流

根据数据的类型分为:字节流和字符流

  • 字节流:以字节为单位(byte),读写数据的流
  • 字符流:以字符为单位(char),读写数据的流
输入流输出流
字节流字节输入流字节输出流
字符流字符输入流字符输出流
  • 字节输入流,在程序中,以字节的方式,将设备(文件、内存、网络等)中的数据读进来
  • 字节输出流,在程序中,以字节的方式,将数据写入到设备(文件、内存、网络等)中
  • 字符输入流,在程序中,以字符的方式,将设备(文件、内存、网络等)中的数据读进来
  • 字符输出流,在程序中,以字符的方式,将数据写入到设备(文件、内存、网络等)中

三、流的结构

几乎所有的流,都是派生自四个抽象的父类型:

  • InputStream ,代表字节输入流类型
  • OutputStream ,代表字节输出流类型
  • Reader ,代表字符输入流类型
  • Writer ,代表字符输出流类型

Java中常用的流及其关系结构,如下:
在这里插入图片描述
注意,一般情况下,一个流,会具备最起码的三个特点:

  • 是输入还是输出
  • 是字节还是字符
  • 流的目的地

其中,流的目的地指定是: 如果是输入流,就表示这个流从什么地方读数据,如果是输出流,就表示这个流把数据写到什么地方!

例如, InputStream ,是所有字节输入流的抽象父类型。那么它的子类型一定是以 字节 的方式,从某个地方把数据 读 取到程序中,只是不同的子类型,它们的目的地 不一样,并且一般可以通过子类型的名字看出它的的目的地是哪里,例如:

  • ByteArrayInputStream ,它是以字节的形式,去读取某个地方的数据,通过名字可以看出,它
    的目的地是字节数组中,也就是以字节的形式从byte数组中读取数据
  • FileInputStream ,它是以字节的形式,去读取某个地方的数据,通过名字可以看出,它的目的
    地是文件,也就是以字节的形式从文件中读取数据

四、字节流

概述

计算机中,存储一切数据(文本、图片、视频等),都是以二进制的形式进行的,最终都是一个一个的字节,所以使用流,进行传输数据的时候,也是一个一个的字节进行的。

  • java.io.InputStream是所有字节输入流的抽象父类型:在这里插入图片描述
  • java.io.OutputStream是所有字节输出流的抽象父类:在这里插入图片描述

在代码中,使用流操作数据的基本步骤是:

  1. 声明流
  2. 创建流
  3. 使用流
  4. 关闭流
控制台

使用字节流,从控制台读取数据,以及向控制台中写数据。

例如:

public class Demo {
	public static void main(String[] args) {
		//1声明流
		InputStream in = null;
		OutputStream out = null;
		//2创建流
		in = System.in;
		out = System.out;
		//3使用流,,这里使用System中已经创建好的流对象
		try {
			int data = -1;
			data = in.read();
			out.write(data);
			data = in.read();
			out.write(data);
			out.flush();//刷新缓冲区,强制所有数据写出去
		} catch (IOException e) {
		
			e.printStackTrace();
		}finally {
			//4关闭流
			if(in!=null) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
			if(out!=null) {
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}
}}

结果如下
在这里插入图片描述

这里是一次读取用一个字节,然后把字节值输出

注意,这个子类中重写的read方法,会让线程阻塞,等待用户在控制台中的输入,用户输入并按下回车,程序中的read方法就从阻塞状态恢复过来,从而读取到用户输入的内容。

也可以一次读取多个字节,然后将本次读取到
的都输出,加入while循环可以让程序一直读取和写出

public class Demo2 {
	public static void main(String[] args) {
		//1声明流
		InputStream in = null;
		OutputStream out = null;
		//2创建流
		in = System.in;
		out = System.out;
		//3使用流
		try {
				byte[] buf = new byte[10];
				int len = -1;
				//循环,一个流不停的读数据,一个流不同的写数据
				while((len=in.read(buf))!=-1) {
					System.out.println(len+":"+Arrays.toString(buf));
					out.write(buf,0,len);//本次读了多几个字节,那么就写出几个字节
				}
				len = in.read(buf);
				
				
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//4关闭流
			if(in!=null) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
			if(out!=null) {
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}
}}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值