IO流失java基础中的重要的一部分,现总结如下:
IO流:
IO流是输入输出流。它可以帮助我们进行信息的交换。
什么是输入,什么是输出?
以程序(内存)为参照来判断。
内存得到信息,就是输入.
内存中的信息写到文件中,就是输出。
IO流的分类
1.按照流的指向来分:输入与输出
2.按照操作的单位:字节流与字符流
1.1字节流
输入流:InputStream
输出流:OutPutStream
1.2字符流
输入流:Reader
输出流:Writer
3.按照流的使用:基本流与复合流
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
对文件进行操作的常用流总结:
1.FileInputStrea 字节输入流
1、构造方法
FileInputStream(File file) 根据文件对象创建输入流
FileInputStream(String name) 根据文件路径创建输入流
2、常用方法
void close() 关闭流
int read() 读取一个字节(这里一定要记得:byte、char、short 在运算的时候会自动类型提升成 int)
如果,到达文件末尾,则返回-1;
返回的 int 是读取到的 字节的码表值
int read(byte[] b) 返回值:是表示读取到了 n 个有效的字节 存储到 byte数组中。 返回-1则达到文件末尾
3、available() ----了解
在开发中一般使用这个方法来判断是否可以读取到信息。
if(fis.available()>0)
fis.read();
2.FileOutputStream 字节输出流
1、构造方法
FileOutputStream(File file) 根据文件对象创建输出流
FileOutputStream(File file, boolean append) 根据文件对象创建输出流,并指定是否追加
FileOutputStream(String name) 和上面差不多,只不过是根据路径
FileOutputStream(String name, boolean append) 和上面差不多
2、常用方法
void close() 关闭流
void write(byte[] b) 把byte数组中的数据写到文件中去
void write(byte[] b, int off, int len) 把byte数组中的一部分数据写出
void write(int b) 把一个字节写出(一定要区分int,了解字节是能自动类型提升的)
疑问: FileOutputStream 中为什么没有 刷新操作
是因为:字节流是最基本的输出单位,所有没必要有,而字符输出流,是通过 字节输出流包装而成的,提高了效率,所以需要把缓冲区的数据刷新
3.FileReader字符输入流
该类的方法,api中没有显示,表示继承的是父类中的方法。去父类查找
该类的使用方法和 字节流的使用差不多。
步骤:
A:创建字符输入流对象
B:调用读取数据方法,并显示
C:释放资源
4.FileWriter字符输出流
步骤:
A:创建字符输出流对象
B:调用写入数据方法,并刷新缓冲区
C:释放资源
flush() 刷新该流的缓冲。
需要注意的就是:
字符流的底层是通过字节来实现的,它通过查找不同的编码表来将信息写入到文件中。
在字符流中它有一个缓冲区。
当我们使用write进行写操作时,它是将信息写入到了缓冲区中,没有直接写入到文件。
那么就出现一个问题,如果流不进行刷新操作,这时信息是在缓冲区中保存,所有
在文件中看不到。
也就是说,当我们进行close操作时,它的底层会调用一个flush方法,来将缓冲区的内容写入到目的地.
java中使用的是unicode编码表,他有65535个字符
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IO中的其他流:
用递归的方式复制多级目录的时候需要自己创建文件目录,然后复制
1.数据输入输出流:
DataOutputStream :
DataOutputStream :
特有的方法:写的方法后面可以跟数据类型,读的时候也需要加上数据类型,且最好要和写的顺序一致,否则可能出现乱码
作用是节省了点空间,但是开发中一般不会用到
2.内存操作流:
ByteArrayOutputStream :
类似的还有 String / Char
3.打印流:
PrintStream: 可以方便的打印各种数据值表示形式,专注于输出,没有相应的输入流,在创建对象的时候可以设置成自动刷新(前提是给一个流对象)
注意:自动刷新必须通过手动设置,切只能使用println/和printf 的方法
printf() 方法:使用指定格式的字符串和参数将格式化的字符串写入,格式需要查表,用%d%插入格式内容,可以设置小数点个数
4.随机访问流:
RandomAccessStream RandomAccessFile 包括对文件的读取和写出
根据不同的模式创建对象
r 以只读的方式打开
rw 打开以便读取和写入 一般使用这种方式
随机访问流是通过 getFilePointer() 来获取读取的指针,通过seek()方法去重设指针位置读写,Android使用的较多
5.序列化流:即对象的持久化存储
objectInputStream
objectOutputStream
将person类序列化到硬盘上:
1创建序列化流对象
2写入对象
3让元素实现Serializable接口
4读取数据即可
实际运用时:
1.使用序列化流将对象持久化到硬件设备上,被持久化的对象必须实现Serializable 接口
2.实际开发过程中,持久化的动作一般由数据库完成,并不会使用序列化流完成。
3.所以实际开发过程中,对象可以不用实现Serializable就可以持久化,但实际上我们还是让所存对象实现持久化接口
4.在持久化过程中,会将序列化ID一同持久化到文件中,读取时就读取当时存取的持久化ID
5.当读取到的持久化ID与程序中类的持久化ID相同,就可以使用这个类来反序列化这个对象
6.如果没有手动给出序列化号,则每次修改类都会产生新的序列化号
注意:对象中的静态数据是不会被持久化的,因为静态属性是类之前加载的,不是对象
非静态数据不想被持久化怎么办?
只要将不需要持久化的非静属性据进行 transient 关键字修饰即可
6.集合:Properties 父类为 Hashtable 属于双列集合 一般存放属性,是一个属性集合
注意:没有泛型!
特有方法:get/setProperty() 特有方法中只能访问String类型的键,获取String 类型的值
这并不说明该集合不能存放其他类型的键值对(但是实际开发过程中确实不放其他类型的键值)
注意:可以和IO流结合起来 使用的方法为 void load().