JAVA笔记二:输入输出

IO类:IO包中绝大部分的类都是由以下四个类直接或间接继承来的
InputStream,OutputStream,Reader,Writer。他们是Object的直接抽象子类。此外还有Serializable接口类,文件类。

:流是在数据(Java程序中可以使用的数据对象)和io设备(比如文件,内存,磁盘,控制台,网络设备)间建立的一个管道。输入和输出都是相对于Java进程而言,InputStream/Reader输入流从io设备中获取数据,OutputStream/Writer输出流将数据输出给io设备。
按流的数据单位分为:字节流(InputStream、OutputStream),字符流(Reader、Writer)。当操作流中的数据含有中文的时候,就必须使用字符流进行读写。
按流的构造函数分为:节点流、处理流(过滤流)。节点流用于和特定设备直接相连,比如ByteArrayInputStream、FileInputStream等;处理流构造时需要依赖已有的节点流才能和设备相连,比如BufferedInputStream、Objectoutputstream、DataInputStream等,大部分使用场景,处理流都是和FileStream配合。
在这里插入图片描述
字节流

1.InputStream的方法:
• close()
• mark(int):调用时记录当前读取位置,后续可通过reset回到该读取位置,一般使用mark(0)。
• reset()
• skip(long 希望跳过不读取的字节数)
• read方法有3种:
⁃ 读取一个byte作为int返回
⁃ 将读取的数据放入一个byte[]
⁃ 将读取指定长度的数据放入一个byte[]
⁃ 达到流末尾返回-1
在这里插入图片描述

2.OutputStream的方法:
• close()
• flush()
• write方法有3种:
⁃ 输出一个byte
⁃ 输出一个byte[]
⁃ 输出一个指定长度的byte[]

在这里插入图片描述
• ByteArrayInput/outputStream:传入内部缓冲区(其实就是一个字节数组,new ByteArrayInputStream(byte buf[]) )作为构造函数入参,为什么不能直接操作数组?无需close(为什么?)。
• CharArrayReader:传入字节数组,new CharArrayReader(char[] buf, int offset, int length)
• PipedInput/OutputStream:从管道中读写数据,必须成对使用,互为构造函数的入参,可以用于线程间的通信。注意read的时候,即使不限制大小,默认一次也只能读取1024个字节。
• FileInput/OutputStream :传入某个文件(String,File 或 FileDescriptor)作为构造函数入参。处理流经常使用本节点流作为入参。
• ObjectInput/OutputStream:处理流,用来读写序列化对象给对应的节点流,所以构造函数需要传参节点流对象实例。
⁃ 类序列化:支持所有实现了Serializable接口的类(out对象实例oos.writeObject(Java对象实例s))。同时,read/writeObject支持重写,在实现的过程中,会通过反射在s中寻找writeObject(参数为ObjectOutputStream)的方法,如果找到了就会调用s.writeObject(oos)方法;没找到的话会使用默认的实现。所以,可以通过在s对象中重写该方法,来实现自己的序列化存储。
⁃ 基本数据类型序列化:out对象实例.writeInt(1234)。
• BufferedInput/OutputStream :处理流,作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”,所以构造函数需要传入一个节点流和一个缓存大小值(不传,默认8192)。BufferedInputStream 本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。
• DataInput/OutputStream:处理流,作用和ObjectStream类似,但不能直接存储对象,只能存储某个基本数据类型的成员变量(采用UTF-8),所以也没有要求序列化的约束条件。
• PrintStream:处理流,唯一一个孤立的Outputstream。作用为为其他输出流添加使它们能够方便地打印各种数据值的功能,所以主要提供了很多print,println数据方法。
• 举例:System.out实际就是一个PrintStream对象实例。
第1步 FileDescriptor fd = FileDescriptor.out;
第2步 FileOutputStream fdOut = new FileOutputStream(fd);
第3步 BufferedOutputStream bufOut = new BufferedOutputStream(fdOut, 128);
第4步 PrintStream ps = new PrintStream(bufout, true);
第5步 setOut0(ps);

字符流

序列化
• Serializable:接口,用于保存Java对象,比如程序停止的时候需要保存一些对象的状态到文件(序列化),当下次启动时再把它们加载回来(反序列化)。也可以用于网络间对象的传输,只要传输的两头对这个对象定义的结构相同。这个接口本身不需要实现者做任何代码开发,JVM已经实现了相关功能(打开保存的序列化文件,看到的也是一堆乱码)。但只能保存不含动态资源(Thread类,Socket类对象,编译会出错)的实例化对象(不保存static变量)的成员变量信息(不保存方法相关的信息),同时transient变量也不会被保存下来。
-serialVersionUID 是用于记录class文件的版本信息的,serialVersionUID这个数字是通过一个类的类名、成员、包名、工程名算出的一个数字,也可以自己编号维护。
• Externalizable:

文件类:对文件类的读写,都依赖FileInput/OutputStream。
• File类:提供文件或者目录的增删查功能。实现了Serializable接口和Comparable接口。实现Serializable接口,意味着File对象支持序列化操作。而实现Comparable接口,意味着File对象之间可以比较大小;File能直接被存储在有序集合(如TreeSet、TreeMap中)。
• Filedescriptor类:为文件的读写功能提供了基础,存放文件或者套接字信息(对于Linux来说,一切皆文件,当应用程序打开一个文件或者建立一个socket连接的时候,内核返回给应用程序一个非负的整数,使用这个称之为filedescriptor的东西来实现对文件或者socket的操作。),是真正代表了操作系统文件对象的东东。通过FileInputStream的getfd方法,可以获得File对应的Filedescriptor。
它有3个static成员变量,(0) in – 标准输入(键盘)的描述符,(1) out – 标准输出(屏幕)的描述符,(2) err – 标准错误输出(屏幕)的描述符。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值