Java I/O操作类

在i/o类中有将近80个类,大致分为四组
1.基于字节操作的I/O接口:InputStream和OutStream
2.基于字符操作的I/O接口:Writer和Reader
3.基于磁盘操作的I/O接口:File
4.基于网络操作的I/O接口:Socket
其实不管是磁盘操作还是网络传输,最小的存储单元还是字节,而不是字符。所以I/O操作的还是字节。那为什么还设有I/O的字符接口?因为我们在程序日常操作中基本都是字符,如果直接用字节操作的I/O接口的话,还需要将字符转换成字节,从字符转成字节要经过编码转换,是一个比较复杂耗时的过程,还容易出现乱码。所以为了方便直接提供一个操作字符的I/O接口。
所以会有字节和字符的转换接口
字节和字符的转换接口
InputStreamReader和OutputStreamWriter
InputStreamReader:将字节的输入流变成字符的输入流
OutputStreamWriter:将 字符的的输出流变成字节的输出流

磁盘的I/O工作机制

我们知道硬盘是由操作系统来管理的,所以我们读取和写入文件I/O操作都需要调用系统提供的接口。而系统为了运行安全,将磁盘分为内核空间地址和用户空间地址。所以再运行的时候这两部分内存是隔离的,保证了操作系统的运行安全,但是总会有需要数据从内核空间传到用户空间的,这就出现了数据在内核空间向用户空间复制的问题。
如果我们用到了再去复制,会非常影响性能。操作系为了加速I/O访问,在内核空间使用了缓存机制,也就是说将从磁盘读取的文件按照一定的组织顺序进行缓存,如果用户程序访问事的是同一段磁盘地址的数据空间,那么操作系统姜葱内核缓存中直接取出返回给用户程序。
标准访问文件方式
标准的访问文件,当程序调用read()接口时,操作系统检查在内核的高速缓存中有没有需要的数据,如果已经有缓存了,那么直接从缓存中返回,如果没有,从磁盘读取,缓存在电脑的缓存了。
写入就是程序调用write()接口将数据从用户空间复制到内核的缓存中,这个时候我们的任务已经完成,从内核缓存写到磁盘中,是操作系统完成的。
直接I/O的方式
也就是我们不经过内核的缓存,直接从磁盘中读取和写入。我们知道程序调用read()接口时,回去程序本身的缓存中找有没有数据,如果没有直接去磁盘中读取。这有这有自己的好处,程序知道哪些是热点数据,也就是常用的数据,能够提高性能,但是如果这个数据不再程序缓存中的话,去磁盘读写会非常的浪费时间,因为I/O操作占用的时间比较长。
同步I/O方式
也就是数据的读取和写入都是同步操作的,只有等到数据成功被写到磁盘时才返回给程序成功的标志。这与标准的访问文件方式不同,标准的文件访问方式把数据复制高速缓存中就可以了,不需要等待从缓存写入磁泡。
异步I/O方式
异步,也就是说调用read()接口访问数据的时候,当线程发送请求后,线程不是等待数据访问成功才去干别的事,线程发送请求后,直接去处理其他事情了。这种方式的好处是,提高程序的效率,但是不影响程序的正常运行。
内存映射方式
内存映射,就是将操作系统中的内存的某一区域和磁盘中的某个文件关联起来,当要访问内存中的某一个数据时,转换成访问文件的某一段数据。

Java序列化

Java序列化就是把对象转换成一串二进制表达的字节数组,通过保存或者转移这些字节数据来达到持久化的目的。反序列化就是将这个字节数组重新构造成对象。序列化的数据并不是想class文件保存了真个类的信息,所以反序列化还是需要原始类作为模板。序列化的接口为Serializable接口。
序列化注意情况
1.当父类实现了Serializable接口时,所有的子类都可以被序列化
2.子类实现了Serializable接口时,父类没有实现,父类的属性不能被序列化,但是子类的属性可以被序列化
3.如果序列化的属性是一个对象,则这个对象也必须是实现Serializable接口,否则报错
4.在反序列化是,如果对象有属性被修改或者删除,则修改的部分会丢失,不出错
具体使用输入和输出流
输入流

public  class MyTest {public static void main(String[] args) throws IOException{File file= new File("e:\\a.txt");if(file.exists()){InputStream in =new FileInputStream(file);int a=0;while((a=in.read())!=-1){System.out.print((char)a);}in.close();}else{System.out.println("文件不存在");}}
}

如上面代码所示,我们能够用inputStream读取文件里的内容

但是我们发现从文件读取的内容英文是没问题,但是中文部分是乱码。由于我们用的是字节流,读取的。没有指定编码,中文字符会乱码。

public  class MyTest {public static void main(String[] args) throws IOException{File file= new File("e:\\a.txt");if(file.exists()){InputStream in =new FileInputStream(file);InputStreamReader inputStreamReader=new InputStreamReader(in,"UTF-8");int a=0;while((a=inputStreamReader.read())!=-1){System.out.print((char)a);}in.close();}else{System.out.println("文件不存在");}}
}

如上面代码,我们将把输入流作为参数传给InputStreamReader,并指定了编码,从字节转成了指定字符。解决了中文乱码问题。
输出流

public  class MyTest {public static void main(String[] args) throws IOException{File file = new File("e:\\b.txt");OutputStream out=new FileOutputStream(file);String str="zxcv";for(int i=0;i<str.length();i++){char a=str.charAt(i);out.write(a);}out.close();    }}

上面的代码就能够往文件里面写内容了,但是每次都是覆盖的,在FileOutputStream的构造方法中有一个在尾部追加的。来看看源码

public FileOutputStream(File file, boolean append)throws FileNotFoundException{String name = (file != null ? file.getPath() : null);SecurityManager security = System.getSecurityManager();if (security != null) {security.checkWrite(name);}if (name == null) {throw new NullPointerException();}if (file.isInvalid()) {throw new FileNotFoundException("Invalid file path");}this.fd = new FileDescriptor();fd.attach(this);this.append = append;this.path = name;open(name, append);}

所以再实例化的时候把参数改为true就好了

OutputStream out=new FileOutputStream(file,true);

但是这个还是没有解决中文乱码的问题

public  class MyTest {public static void main(String[] args) throws IOException{File file = new File("e:\\b.txt");OutputStream out=new FileOutputStream(file,true);OutputStreamWriter outputStreamWriter=new OutputStreamWriter(out,"UTF-8");String str="zxcv 陈";outputStreamWriter.write(str);outputStreamWriter.flush();out.close(); }
}

使用OutputStreamWriter就可以解决,从字符到字节流中的问题了。
这里介绍了从硬盘中读入和写入的过程,接下来看看,线程与线程之间是如何通信的。
I/O管道
两个线程是独立的,想要进行通信可以一方采用PipedInputStream另一方采用PipedOutputSream,这样就进行通信了。
带缓冲的字符流
带缓冲区的字符输入,可以提高熟读IO处理的速度,可以一次读取一大块数据,而不需要每次从硬盘中一次读取一个字节。
BufferedReader和BufferedInputStream
BufferedWriter
也可以指定缓冲区的大小,

public BufferedInputStream(InputStream in, int size) {super(in);if (size <= 0) {throw new IllegalArgumentException("Buffer size <= 0");}buf = new byte[size];}

不指定大小的话

public BufferedInputStream(InputStream in) {this(in, DEFAULT_BUFFER_SIZE);
}

使用的是默认的大小,8kb

private static int DEFAULT_BUFFER_SIZE = 8192;

本文属于自己参考文章和结合自己的总结来学习和巩固Java基础

参考文章:https://github.com/h2pl/Java-Tutorial/blob/master/docs/java/basic/1%E3%80%81%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E5%9F%BA%E7%A1%80.md

深入了解Java I/O的工作机制相关推荐

  1. 深入分析 Java I/O 的工作机制

    深入分析 Java I/O 的工作机制 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代 ...

  2. 深入分析 Java I/O 的工作机制--转载

    Java 的 I/O 类库的基本架构 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代, ...

  3. 深入分析Java I/O的工作机制 (三)网络I/O的工作机制 很详细

    3.网络I/O的工作机制 前言:数据从一台主机(服务端)发送到网络中的另一台主机(客户端)需要经过很多步骤:首先需要有相互沟通的意向.其次要有能够沟通的物理渠道(物理链路):是通过电话,还是直接面对面 ...

  4. (转)深入分析 Java I/O 的工作机制

    Java 的 I/O 类库的基本架构 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代, ...

  5. Java 并发编程解析 | 如何正确理解Java领域中的锁机制,我们一般需要掌握哪些理论知识?

    苍穹之边,浩瀚之挚,眰恦之美: 悟心悟性,善始善终,惟善惟道! -- 朝槿<朝槿兮年说> 写在开头 提起Java领域中的锁,是否有种"道不尽红尘奢恋,诉不完人间恩怨"的 ...

  6. java语言的实现机制_JAVA语言之Java NIO的工作机制和实现原理介绍

    本文主要向大家介绍了JAVA语言之Java NIO的工作机制和实现原理介绍,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 前言 本文只简单介绍NIO的原理实现和基本工作流程 I/O和 ...

  7. java io工作机制_深入分析Java I/O 工作机制

    前言 :  I/O 问题是Web 应用中所面临的主要问题之一.而且是任何编程语言都无法回避的问题,是整个人机交互的核心. java 的I/O类操作在java.io 包下,将近80个子类, 大概可以分成 ...

  8. 【Java从0到架构师】Zookeeper - 安装、核心工作机制、基本命令

    分布式基石 Zookeeper 框架全面剖析 Zookeeper 安装.配置.运行 Zookeeper 的核心工作机制 特性 数据结构.节点 基本操作命令 服务器的启动和监控 客户端连接 创建节点 查 ...

  9. JavaWeb技术内幕二:Java IO工作机制

    IO问题是当今web应用所面临的主要问题之一,因为数据在网络中随处流动,在这个流动过程中都涉及IO问题,并且大部分应用的瓶颈都是IO瓶颈. 本章将从IO的角度出发,介绍IO类库的基本架构,磁盘IO的工 ...

最新文章

  1. 学习js权威指南第五站 ---- 数组
  2. c语言最小元素下标怎么看,查找最小的k个元素 (C语言代码)
  3. python随机出100道加法题_自动出题随机100题-20以内加减法全部算式
  4. linux命令mount是什么,Linux命令——mount、umount
  5. 【TSP】基于matlab GUI免疫算法结合蚁群算法求解旅行商问题【含Matlab源码 1910期】
  6. MicroSIP 编译教程 VS2017-x86版本
  7. 网站应用和服务器管理(课程总结4)Week12 澳大利亚维多利亚大学VIT1204 Web Application and Server Management
  8. 网路连接配置和DNS服务?解决无线网卡连接WIFI问题(硬件和驱动没问题)?
  9. awk 分隔符 多个空格_awk多分隔符
  10. 《团队软件过程(修订版)》—第2章2.3节团队是什么
  11. 渗透测试-红/蓝队Hvv技术手册/面试
  12. MATLAB教学_06进阶绘图
  13. 2021暑假学习计划
  14. moinmoin 1.9.7 成功移机记录
  15. 【分享】查询分析器显示了完整的字段信息
  16. Outline Of Sodoku
  17. 批量多开独立Google浏览器
  18. 学习笔记(01):教你玩转HTML(html5)h5网页设计,网站开发-strong
  19. 淘宝客订单API获取订单代码
  20. QPalette的详细使用示例

热门文章

  1. 吃鸡 python开发_python实现《吃鸡大法》加文字识别 玩转百万英雄!
  2. cnpm i安装报错-Install fail! Error: Unsupported URL Type: npm:vue-loader@^15.9.7
  3. 数据透视表右侧字段不见了,怎么办?
  4. opencv学习——轮廓分析寻找近似圆
  5. Go上的极简OpenGL开发笔记(二)
  6. 微信之获取微信的openid(二)详细版
  7. tampermonkey油猴插件-tampermonkey油猴插件下载
  8. 看老外的Meego手机设计
  9. 【系统重装】取消U盘分区
  10. volice java_Volice