io流分类
-
按照高低级别:
(1)高级流:字符流
(2)低级流:字节流 -
按数据流向:
(1)输入流InputStream:从外部设备到计算机的数据流动
(2)输出流OutputStream:从计算机到外部设备的数据流动 -
按照数据类型:
(1)字节流:用于读写字节类型的数据(包括ASCII表中的字符)类可以分为InputStream及其子类,OutputStream及其子类
(2)字符流:用于读写字符(16位Unicode码)包括Reader类及 其子类 和Writer类及其子类
-
常用字节流类型的区别
(1)DateInputstream:数据输入流允许应用程序以与机器无关方式从基础输入流中读取基本java数据类型,应用程序可以使用数据输出流写入后由数据输出流读取的数据
(2)ByteArrayInputStream:包含一个内部缓冲流,被称为内存流,该缓存区存储从流中读取的字节,内部计数器跟总read方法要提供的下一个字节。
关闭ByteArrayInputStream无效,此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException
(3)FileInputStream类:此类是字节输入流,是InputSteam类的子类,常用的构造方法:
1)Public FileInputStream(String name)throws FileNotFoundException(String name是一个完整的路径名)
2)Public FileInputStream(File file)throws FileNotFoundException(根据file对象创建文件)
(4)FileOutputStream类:此类是字节输出流,是OutputStream类的子类,常用的构造方法
1)Public FileOutputStream(String name)String name 是完整的路径
2)Public FileOutputStream(String name,boolean append)String name 是完整的类路径
(5)拓展:乱码
1)产生的原因:编码规则与解码规则不一样
2)出现的地方:
文件保存的编码格式与内容的编码格式不一样
控制台乱码
IDE的工作空间没有指定编码格式
数据源的编码格式没指定 -
使用流的步骤
(1)使用file类打开一个文件
(2)通过字节流或字符流的子类,指定输出的位置
(3)进行读/写操作
(4)关闭输入/输出
-
BufferedReade
从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途。
通常,由读取器做出的每个读取请求将引起对底层字符或字节流的相应读取请求。 因此,建议将BufferedReader包装在其read()操作可能昂贵的读取器上,例如FileReaders和InputStreamReaders。 例如,
BufferedReader in = new BufferedReader(new FileReader(“foo.in”));
将缓冲指定文件的输入。 没有缓冲,每次调用read()或readLine()可能会导致从文件中读取字节,转换成字符,然后返回,这可能非常低效。
使用DataInputStreams进行文本输入的程序可以通过用适当的BufferedReader替换每个DataInputStream进行本地化
-
缓存流
缓存是IO的一种性能优化,缓存流为IO流增加了内存缓存区,有了缓存区,就可以减少系统直接与硬盘之间交互传输的次数,增加每次传送的数据量,借以提高传输效率,保护硬件
有了缓冲功能,则会将输出的内容先放置在内存中,等到有一定数据量的时候,或是流关闭,或调用flush()方法时,才会将相应的内容保存在硬盘或其他目的地
分为BufferedInputStream和BufferedOutputStream两类
(1)BufferedInputStream类
BufferedInputStream类可以对所有的InputStream类进行带缓存区的包装,以达到性能的优化,此类提供了两个构造方法:
BufferedInputStream(InputStream in)
此形式的构造方法创建了一个带有32位字节的缓存流
BufferedInputStream(InputStream in ,int size)
此形式的构造方法按指定的大小(字节)来构造缓存流
(2)BufferedOutputStream类
BufferedOutputStream类可以对所有的OutputStream类进行带缓存区的包装,已达到性能的优化,两个构造方法:
BufferedOutputStream(OutputStream out)
此方式创建了一个带有32个字节的缓存流
BufferedOutputStream(OutputStream out,int size)
此方式按指定的大小(字节)来构造缓存流 -
关闭流:不关闭会造成资源浪费
-
字节流任何情况都可以用,字符流只有文字的情况下使用
-
流的分组
基于字节操作的I/O:InputStream类及其子类。OutPutStream类及其子类
基于字符操作的I/O:Writer类及其子类,Reader类及其子类
基于磁盘操作的I/O:File
基于网络操作的I/O:socket
-
序列化和反序列化(对象流)
(1)网址:https://www.cnblogs.com/ysocean/p/6870069.html
(2)序列化:指把堆内存中的 Java 对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他网络节点(在网络上传输)。这个过程称为序列化。通俗来说就是将数据结构或对象转换成二进制串的过程
(3)反序列化:把磁盘文件中的对象数据或者把网络节点上的对象数据,恢复成Java对象模型的过程。也就是将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程
(4)如何使用序列化
- 让类实现Serializable接口,该接口是一个标志性接口,标注该类对象是可被序列
- 然后使用一个输出流来构造一个对象输出流并通过writeObect(Obejct)方法就可以将实现对象写出
- 如果需要反序列化,则可以用一个输入流建立对象输入流,然后通过readObeject方法从流中读取对象
- io流获取文件的大小
一种是使用File的length()方法;另外一种是使用FileInputStream的available()方法,当InputStream未进行read操作时,available()的大小应该是等于文件大小的。但是在处理大文件时,后者会发生问题。我们来看一下:
(1)使用FileInputStream的available()方法
public static void main(String[] args) {
FileInputStream fis= null;
try{
File f= new File("D:\\CentOS-6.5-x86_64-bin-DVD1.iso");
fis= new FileInputStream(f);
logger.info(fis.available());
}catch(Exception e){
logger.error(e);
} finally{
if (null!=fis){
try {
fis.close();
} catch (IOException e) {
logger.error(e);
}
}
}
}
(2)使用File的length()方法
public static void main(String[] args) {
File f= new File("D:\\CentOS-6.5-x86_64-bin-DVD1.iso");
if (f.exists() && f.isFile()){
logger.info(f.length());
}else{
logger.info("file doesn't exist or is not a file");
}
}
- 使用流如何避免覆盖
用这个方法public FileOutputStream(String name,boolean append)throws FileNotFoundException,将逻辑值append设为false时,写入的字节数据覆盖文本原来的内容,为ture是即追加到原来文本的末尾。覆盖原文本内容如:FileOutputStream x=new FileOutputStream(“文件全路径”,false);throws FileNotFoundException为抛出异常。