java IO概要

来源:互联网 发布:k-means java 编辑:程序博客网 时间:2024/06/04 01:22

详细地址:https://www.ibm.com/developerworks/cn/java/j-lo-javaio/

1、概念
输入输出是相对于内存设备而言的。
输入流:把能够读取一个字节序列的对象称为输入流;
输出流:把能够写一个字节序列的对象称为输出流
输入流和输出流中间连接着内存,输入流和输出流将读写分离开来进行操作,先从外设读入内存,然后再写出内存转移到其他外设

2、分类
基于字节操作的 I/O 接口:InputStream 和 OutputStream
基于字符操作的 I/O 接口:Writer 和 Reader
基于磁盘操作的 I/O 接口:File
基于网络操作的 I/O 接口:Socket

3、字节流
用字节流处理字符数据可能会有编码问题,因为字节流是以字节为单位,没有编码,而字符流是以字符为单位传送数据,字符流即以字节流+编码

两个顶层父类 (抽象类)及实现类:
InputStream(读入内存) :所有字节输入流相关类的父类
OutputStream(写出内存):所有和输出字节流相关类的父类

4、字符流
两个顶层父抽象类及其实现类
Reader:for reading character streams
Writer:for writing to character streams (字符流的写操作基本上后面都需要进行flush()操作)
1、输入输出是相对于内存设备而言的。
输入流:把能够读取一个字节序列的对象称为输入流;
输出流:把能够写一个字节序列的对象称为输出流
输入流和输出流中间连接着内存,输入流和输出流将读写分离开来进行操作,先从外设读入内存,然后再写出内存转移到其他外设

5、字节流和字符流的转化
InputStreamReader 类是字节到字符的转化桥梁,InputStream 到 Reader 的过程要指定编码字符集,否则将采用操作系统默认字符集,很可能会出现乱码问题。
StreamDecoder 正是完成字节到字符的解码的实现类。

6、磁盘IO
将数据持久化到物理磁盘,下面将介绍如何将数据持久化到物理磁盘的过程。

当传入一个文件路径,将会根据这个路径创建一个 File 对象来标识这个文件,然后将会根据这个 File 对象创建真正读取文件的操作对象,这时将会真正创建一个关联真实存在的磁盘文件的文件描述符 FileDescriptor,通过这个对象可以直接控制这个磁盘文件。由于我们需要读取的是字符格式,所以需要 StreamDecoder 类将 byte 解码为 char 格式,至于如何从磁盘驱动器上读取一段数据,由操作系统帮我们完成。

7、Socket
主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接,而建立 Socket 连接必须需要底层 TCP/IP 协议来建立 TCP 连接。建立 TCP 连接需要底层 IP 协议来寻址网络中的主机。我们知道网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机,但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过 TCP 或 UPD 的地址也就是端口号来指定。这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。

8、NIO 的工作方式(非阻塞式IO)
9、IO调优
①磁盘 I/O 优化
提升磁盘 I/O 性能通常的方法有:

  1. 增加缓存,减少磁盘访问次数
  2. 优化磁盘的管理系统,设计最优的磁盘访问策略,以及磁盘的寻址策略,这里是在底层操作系统层面考虑的。
  3. 设计合理的磁盘存储数据块,以及访问这些数据块的策略,这里是在应用层面考虑的。如我们可以给存放的数据设计索引,通过寻址索引来加快和减少磁盘的访问,还有可以采用异步和非阻塞的方式加快磁盘的访问效率。
  4. 应用合理的 RAID 策略提升磁盘 IO,RAID数据被平均写到多个磁盘阵列中,写数据和读数据都是并行的。

②网络 I/O 优化

  1. 一个是减少网络交互的次数
  2. 减少网络传输数据量的大小:减少网络数据量的办法通常是将数据压缩后再传输
  3. 尽量减少编码:通常在网络 I/O 中数据传输都是以字节形式的,也就是通常要序列化。但是我们发送要传输的数据都是字符形式的,尽量提前将字符转化为字节,或者减少字符到字节的转化过程。
  4. 根据应用场景设计合适的交互方式:所谓的交互场景主要包括同步与异步阻塞与非阻塞方式

同步:
所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。

异步:
不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。我们可以用打电话和发短信来很好的比喻同步与异步操作。

同步能够保证程序的可靠性,而异步可以提升程序的性能。

阻塞与非阻塞:主要是从 CPU 的消耗上来说的。
阻塞:CPU 停下来等待一个慢的操作完成 CPU 才接着完成其它的事。
非阻塞:在这个慢的操作在执行时 CPU 去干其它别的事,等这个慢的操作完成时,CPU 再接着完成后续的操作,但线程切换次数增加。

面试题:简述一下将文件中的数据输入到另一个文件中的步骤
1.首先创建File对象,并且和需要操作的文件相关联,这时候需要对文件进行判断是否存在,不存在则会报错

2.既然是读取文件并且写到文件,属于纯文本,可以选择FileReader和FileWriter进行读写操作,如果出现乱码可以使用其父类指定编码方式

3.创建FileReader对象用于读取文件中的数据,这里可以使用缓冲流进行处理,提高效率,创建一个BufferedReader对象

BufferedReader buffr = new BufferedReader(new InputStreamReader(new FileReader(file)));

4.创建FileWriter,同上使用缓存

public class Demo6 {      public static void main(String[] args){          File origin = new File("d:/helloWorld.txt");          File destination = new File("d:/helloWorld6.txt");          InputStreamReader in = null;          OutputStreamWriter out = null;          BufferedReader reader = null;          BufferedWriter writer = null;          if (!origin.exists()){              try {                  origin.createNewFile();              } catch (IOException e) {                  e.printStackTrace();              }          }          try {              reader = new BufferedReader(new InputStreamReader(new FileInputStream(origin),"ISO-8859-1"));  //            reader = new BufferedReader(new FileReader(origin));              writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination),"ISO-8859-1"));              String line = null;              while ((line = reader.readLine())!=null){                  writer.write(line);                  writer.newLine();              }              writer.flush();          } catch (IOException e) {              e.printStackTrace();          } finally {              if (in!=null){                  try {                      in.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }              if (out!=null){                  try {                      out.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }              if (reader!= null){                  try {                      reader.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }              if (writer!=null){                  try {                      writer.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }          }      }  } 
0 0