您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

Java I/O 入门篇

时间:2019-11-11 10:32:40  来源:  作者:

对于JAVA I/O来说,I意味着Input(输入),O意味着Output(输出)。读书写作并非易事,而创建一个好的I/O系统更是一项艰难的任务。

古人云:“读书破万卷,下笔如有神”。也就是说,只有大量的阅读,写作的时候才能风生水起——写作意味着输出(我的知识传播给他人),而读书意味着输入(从他人的知识中汲取营养)。

01、数据流之字节与字符

Java所有的I/O机制都是基于 数据流 进行的输入输出。数据流可分为两种:

1)字节流,未经加工的原始二进制数据,最小的数据单元是 字节 。

2)字符流,经过一定编码处理后符合某种格式规定的数据,最小的数据单元是 字符 ——占用两个字节。

OutputStream 和 InputStream 用来处理字节流; Writer 和 Reader 用来处理字符流; OutputStreamWriter 可以把 OutputStream 转换为 Writer , InputStreamReader 可以把 InputStream 转换为 Reader 。

Java的设计者为此设计了众多的类,见下图。

Java I/O 入门篇

 

看到这么多类,你一定感觉头晕目眩。反正我已经看得不耐烦了。搞这么多类,看起来头真的大——这也从侧面说明实际的应用场景各有各的不同——你也完全不用担心,因为实际项目当中,根本就不可能全用到(我就没用过 SequenceOutputStream )。

我建议你在 学习的时候要掌握一种“挑三拣四”的能力 ——学习自己感兴趣的、必须掌握的、对能力有所提升的知识。切不可囫囵吞枣,强迫自己什么都学。什么都学,最后的结果可能是什么都不会。

字符流是基于字节流的,因此,我们先来学习一下字节流的两个最基础的类—— OutputStream 和 InputStream ,它们是必须要掌握的。

1)OutputStream

OutputStream 提供了4个非常有用的方法,如下。

其子类 ByteArrayOutputStream 和 BufferedOuputStream 最为常用(File相关类放在下个小节)。

①、 ByteArrayOutputStream 通常用于在内存中创建一个字节数组缓冲区,数据被“临时”放在此缓冲区中,并不会输出到文件或者网络套接字中——就好像一个中转站,负责把输入流中的数据读入到内存缓冲区中,你可以调用它的 toByteArray() 方法来获取字节数组。

来看下例。

ByteArrayOutputStream 的责任就是把 InputStream 中的字节流“一字不差”的读出来——这个工具方法很重要,很重要,很重要——可以解决粘包的问题。

②、 BufferedOuputStream 实现了一个缓冲输出流,可以将很多小的数据缓存为一个大块的数据,然后一次性地输出到文件或者网络套接字中——这里的“缓冲”和 ByteArrayOutputStream 的“缓冲”有着很大的不同——前者是为了下一次的一次性输出,后者就是单纯的为了缓冲,不存在输出。

来看下例。

使用 BufferedOuputStream 的时候,一定要记得调用 flush() 方法将数据从缓冲区中全部输出。使用完毕后,调用 close() 方法关闭输出流,释放与流相关的系统资源。

2)InputStream

InputStream 也提供了4个非常有用的方法,如下。

其子类 BufferedInputStream (缓冲输入流)最为常用,效率最高(当我们不确定读入的是大数据还是小数据)。

无缓冲流上的每个读取请求通常会导致对操作系统的调用以读取所请求的字节数——进行系统调用的开销非常大。但缓冲输入流就不一样了,它通过对内部缓冲区执行(例如)高达8k字节的大量读取,然后针对缓冲区的大小再分配字节来减少系统调用的开销——性能会提高很多。

使用示例如下。

先来看一个辅助方法 byteToInt ,把字节转换成int。

再来看如何从输入流中,根据指定的长度contentLength来读取数据。 readBytes() 方法在之前已经提到过。

我敢保证,只要你搞懂了字节流,字符流也就不在话下——所以,我们在此略过字符流。

02、File类

前面我们了解到,数据有两种格式:字节与字符。那么这些数据从哪里来,又存往何处呢?

一个主要的方式就是从物理磁盘上进行读取和存储,磁盘的唯一最小描述就是文件。也就是说上层应用程序只能通过文件来操作磁盘上的数据,文件也是操作系统和磁盘驱动器交互的一个最小单元。

在Java中,通常用 File 类来操作文件。当然了,File不止是文件,它也是文件夹(目录)。File类保存了文件或目录的各种元数据信息(文件名、文件长度、最后修改时间、是否可读、当前文件的路径名等等)。

通过File类以及文件输入输出流( FileInputStream 、 FileOutputStream ),可以轻松地创建、删除、复制文件或者目录。

这里,我提供给你一个实用的文件工具类——FileUtils。

限于篇幅,就不贴太多代码了,需要的话找我(微信:qing_gee)要。

03、网络套接字——Socket

虽然网络套接字( Socket )并不在java.io包下,但它和输入输出流密切相关。 File 和 Socket 是两组主要的数据传输方式。

Socket 是描述计算机之间完成相互通信的一种抽象。可以把 Socket 比作为两个城市之间的交通工具,有了交通工具(高铁、汽车),就可以在城市之间来回穿梭了。交通工具有多种,每种交通工具也有相应的交通规则。 Socket 也一样,也有多种。大部分情况下,我们使用的都是基于 TCP/IP 的套接字——一种稳定的通信协议。

Java I/O 入门篇

 

假设主机A是客户端,主机B是服务器端。客户端要与服务器端通信,客户端首先要创建一个 Socket 实例,操作系统将为这个 Socket 实例分配一个没有被使用的本地端口号,并创建一个套接字数据结构,直到这个连接关闭。

示例如下。

与之对应的,服务端需要创建一个 ServerSocket 实例,之后调用 accept() 方法进入阻塞状态,等待客户端的请求。当一个新的请求到来时,将为这个连接创建一个新的套接字数据结构。

示例如下。

Socket 一旦打通,就可以通过 InputStream 和 OutputStream 进行数据传输了。

04、压缩

Java I/O 支持压缩格式的数据流。在 Socket 通信中,我常用 GZIPOutputStream 和 GZIPInputStream 来对数据流进行简单地压缩和解压。

压缩的好处就在于能够减小网络传输中数据的体积。代码如下。



Tags:Java   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
面向对象的特征之一封装 面向对象的特征之二继承 方法重写(override/overWrite) 方法的重载(overload)和重写(override)的区别: 面向对象特征之三:多态 Instanceof关键字...【详细内容】
2021-12-28  Tags: Java  点击:(2)  评论:(0)  加入收藏
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  Tags: Java  点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Tags: Java  点击:(5)  评论:(0)  加入收藏
1、通过条件判断给变量赋值布尔值的正确姿势// badif (a === 'a') { b = true} else { b = false}// goodb = a === 'a'2、在if中判断数组长度不为零...【详细内容】
2021-12-24  Tags: Java  点击:(6)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  Tags: Java  点击:(11)  评论:(0)  加入收藏
传统游戏项目一般使用TCP协议进行通信,得益于它的稳定和可靠,不过在网络不稳定的情况下,会出现丢包严重。不过近期有不少基于UDP的应用层协议,声称对UDP的不可靠进行了改造,这意...【详细内容】
2021-12-23  Tags: Java  点击:(12)  评论:(0)  加入收藏
文章目录1、Quartz1.1 引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version></dependency>...【详细内容】
2021-12-22  Tags: Java  点击:(12)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  Tags: Java  点击:(11)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  Tags: Java  点击:(17)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  Tags: Java  点击:(19)  评论:(0)  加入收藏
▌简易百科推荐
面向对象的特征之一封装 面向对象的特征之二继承 方法重写(override/overWrite) 方法的重载(overload)和重写(override)的区别: 面向对象特征之三:多态 Instanceof关键字...【详细内容】
2021-12-28  顶顶架构师    Tags:面向对象   点击:(2)  评论:(0)  加入收藏
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(12)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(13)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(11)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(11)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(17)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(19)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(22)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条