java i o是什么流_【Java】I/O流的操作、认识使用
重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。
1、序
在 Java 编程中,I/O流的操作是必须学会的一项技能。无论是文件的复制粘贴,还是上传下载,无论是文本的读取写入,还是音视频的播放,都离不开I/O流的加持。I/O流如此重要,怎么能不了解它!本文将带你了解在Java里,如何自如的操控各种流。
2、理解
网上教程千千万,学校教材万千千,无数遍的使用水流来比喻Java里的I/O流。这无疑是一个非常恰当合适的比喻,但依旧不能解开每个人对流的疑问,当然也包括本文,不一定能被每个人理解,但希望哪怕一个人能够理解。
我也将使用水流来作比喻。现在,要将一个湖里的所有水全部转移到另一个水库里面,怎么办?当然是用抽水机啊,要么就用桶不同的挑嘛。为了能够更好地结合程序来理解,咱们假设选择了使用桶挑水过去的方案。
随即便产生了下面图案:
有了这张图,对Java里I/O的理解就会更加简单一点。见名知意,为啥叫I/O流,是因为在java中,流的操作是通过 两个类的协同操作进行完成的。
这两个分别是:
I: InputStream 输入流
O: OutputStream 输出流
下面分别进行简述:
(1)、InputStream 输入流
输入流和输出流都是相对于程序来进行称呼的。脱离了程序,不能确定某个流就是输入或输出流,下图中“桶”就相当于是程序,那么输入流是什么,一目了然:
可见,从湖泊A 到桶里的这部分水流,就可以说是输入流,但你不能单纯的认为就是这一通水就是输入流,而应该理解为:整个湖里的水,在放入桶的这个行为过程中,这时这些水对于这个桶来说是输入流。
所以同样的,在程序里,数据流在往程序里跑时这个数据流叫做输入流,承载这个数据跑到程序里面的类,是InputStream。
(2)、OutputStream 输出流
与输入流相似,想必你看了上面的输入流,你对输出流可能也有那个概念了,只不过是反其道而行之的,如图所示:
从桶里,往湖泊B倒水,这个行为过程中,所有的湖泊里的水,这可理解为输出流。在程序里,数据流在往程序外跑时,这个流叫做输出流,承载这个数据跑到外面去的类,是OutputStream。
上诉的输入流,输出流都是对于程序来说的,把桶比作是这个运输水的程序,所以在阐述是都是以“桶”为对象来阐述的。
3、代码加入
(1)、InputStream 输入流
首先讲述InputStream输入流的代码应用。InputStream是一个abstract的抽象类,抽象类是不能直接实例化对象的,所以,Java为我们贴心的实现了许许多多的、用于处理各种场景的输入流类,比较常用的FileInputStream可见名知意,它是专门为读取文件而生的文件输入流承载对象。下面是文件输入流的使用案例:
// 为了保证程序的正常,请在D盘下建立文件:file.txt,文件内容:File Inputstream test.
// FileInputStream 在 java.io 包下,如果使用文本编辑器编写代码,记得导包:import java.io.FileInputStream;
public class Test {
public static void main(String[] args) throws Exception {
// 使用指定文件构建文件来构建文件输入流。
FileInputStream fileInputStream = new FileInputStream("D:/file.txt");
// 就如同上图要把一个湖泊里面的水全部传到另一个湖泊,中间借助了一个“桶”来帮助。
// 并且,上面将“桶”比喻为整个程序。
// 现在要摈弃:将“桶”比喻为整个程序。这个概念了。
// 实际上“桶”只能充当程序里的一个变量。
// 这个变量每次能容纳一定容量的数据。
// 这里定义 datas 数组。是一个每次只能容纳4字节的“小桶”。
byte[] datas = new byte[4];
// 但是我们不能确定是不是每次重复用这只“桶”去舀水的时候都能把桶舀满。
// 就比如上边图中,当桶儿把湖泊A里的水快舀完时,有一个人提着桶去舀最后一桶水,发小并不能舀满
// 一整桶水,他索性舀了多少就带走多少了。
// 而在程序里,程序是是的,它必须要你告诉他每次舀了多少水,
// 特别是在最后一次没能舀满一“桶”水时,这个标记了舀了多少水的字段就必不可少了。
// 定义一个字段表示每次舀了多少水。
int size = 0;
// 舀水一次可能完不成,毕竟我们桶只有这么大,所以要来来回回不同的舀,即循环进行。
// 有人可能说,你定义一个超大的桶,不就可以一次搞定了。
// 答:可以是可以,但是要明白,这个过程中是要把数据保存在你电脑的内存条上的,假如你的文件有100GB,你又定义了一个100GB的桶
// 而你的电脑内存一共才16GB,程序一运行就会内存溢出的,直接报错了。
// 所以桶的大小,要根据电脑内存有多大,读取行为发生的频率大不大来自己权衡的一个数值。
// 下面开始循环读取
while (size != -1) {
// 当文件读取完成后, read 方法会返回 -1来表示已经读取完成了,所以,只要不是 -1 就一定表示数据还能继续读取。
// 输入流的读取的方法会返回当前实际读取了多少数据的大小,正合适告诉我们舀了多少水。
size = fileInputStream.read(datas);
// 此时 datas 里面的数据就已经是舀到的数据了。
// 拿到数据构建字符串:
String str = new String(datas);
// 输出结果:
System.out.print(str);
}
// 当循环完成,也就表示读取完成,水舀完了。
// 不要忘了最后调用输入流的关闭方法,你要是不调用关闭方法,就如同占着茅坑不拉屎是一样的道理。
fileInputStream.close();
}
}
运行这个程序,最后输出:File Inputstream test.
加上代码中的注释,相信理解起来非常简单。这是一个非常典型的代码编写方式,所有的输入流几乎都是这样的代码流程来进行数据的读取。
(2)、OutputStream 输出流
输入流是讲数据从程序的外部读入到程序的内部,那么输出流就是将数据从程序的内部输出到程序的外部,上面使用了一个简单的程序将外部文件“file.txt”的内容读取到了程序内部并显示,现在,我们要在程序内部设定好一个字符串,然后输出到文件中,同输入流一样,这里也采用文件相关的“FileOutputStream”文件输出流,来完成数据的输出。示列代码如下:
public class Test {
public static void main(String[] args) throws Exception {
// 准备好要输出的数据内容。
String str = "File OutputStream test.";
// 构建文件输出流:
FileOutputStream fileOutputStream = new FileOutputStream("D:/outFile.txt");
// 无论是流的输出,还是流的读取,它们操作的数据都是 byte 的二进制数据。
// 而定义的准备用于输出数据是字符串,所以,需要先从字符串转换成 byte 二进制数据。
byte[] datas = str.getBytes();
// 将数据写到输出流。
fileOutputStream.write(datas);
// 这一步很重要。
// 上面一行代码是将数据写入到了一个磁盘缓存区,内容其实(可能)还没有真的被写入到文件里。
// 这一行代码的调用,可以强制的将数据从缓存区强制的写入的文件中,所以为了保证效果,务必每次在 “关闭” 输出流前
// 记住要调用一次该方法。
fileOutputStream.flush();
// 最后不要忘了关闭输出流。
fileOutputStream.close();
}
}
运行程序,会在磁盘D盘下多出一个 outFile.txt 文件,打开这个文件,就可以看到文件内容:File OutputStream test.
你发现这个输出流并没有像输入流那样去循环的进行输出。是的,因为这里是为了让咱们快速理解输出流的使用方式,只是单独的进行单向输出,而且输出的只有几个字,我们能确定它的大小不是很大。为什么上面输入流读取的文件也很小,而我们也是用循环读取?因为我们只是在测试学习,知道这个文件不大,实际开发中,你永远不知道你要读取的文件有多大,对于我们不知道的事物,我们应该采取兼容性最大的程序代码方式去编写。所以输入时往往使用循环来读取。
现在了解了输入流,输出流,最有魅力的地方不是单独使用它们,而是将它们结合起来使用,达到更加强悍的功能。耳熟能详的的复制功能,就可以通过输入流,输出流的相互配合完成。
4、结合使用
将输入流,输出流结合起来,学会I/O流的一个关键环节,任何输出流,输入流都可以相互结合,而不一定只能是文件的输入流对上文件的输出流。假如现在我们有一个 1GB 大小的 视频文件《video.mp4》在D盘根目录,要把它复制到 E盘下。示列代码如下:
public class Test {
public static void main(String[] args) throws Exception {
// 视频文件路径。
String videoFile = "D:/video.mp4";
// 建立输入流
FileInputStream fileInputStream = new FileInputStream(videoFile);
// 准备一个小“桶”每次舀这么多数据。
byte[] datas = new byte[1024];
// 每次舀水的量
int size = 0;
// ---------------------------------------------------------------
// 准备输出文件路径
String targetFile = "E:/video.pm4";
// 建立输出流
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
// 循环的使用“小桶”舀。
while (size != -1) {
// 舀
size = fileInputStream.read(datas);
// 舀到数据,往目标倒。
// 因为我们使用 size 标记每次舀了多少水,所以这里写的时候,也要讲“桶里”有多少水这个信息
// 告诉写出的位置,这样就能拿在桶里拿到正确的数据量。
fileOutputStream.write(datas, 0, size);
}
// 完成操作,关闭输入流,关闭输出流
fileInputStream.close();
fileOutputStream.close();
// 提示完成
System.out.println("复制完成!");
}
}
执行程序,将会把D盘下的文件复制一份在E盘下,这样就完成了文件的复制,同时对文件输入流,输出流有了更深刻的印象。在Java里,流的操作中心都是围绕
read读的方法,和write写的方法,无论怎么样,只要搞清楚各个类是用来干嘛的以及明白数据流向的方向,就能轻松的理解流的操作了。
java i o是什么流_【Java】I/O流的操作、认识使用相关推荐
- java io流_浅谈IO流(一)-流的基本概念以及java的常见流
对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能.程序运行需要数据,数据的获取往往需要跟外部系统进行通信,外部系统可能是文件.数据库.其他程序.网络.IO设备等等. ...
- feed流和瀑布流_推荐系统之Feed流UI交互设计
前面几篇介绍了推荐系统相关的标签.画像.算法.策略,整体上看推荐系统是一个偏工程应用的领域,要想在商业产品中引入推荐系统,利用推荐系统来帮助用户过滤信息,除了构建精准高效的推荐算法外,还需要设计适合特 ...
- feed流和瀑布流_什么叫feed流?
从结构来看,很多社交和资讯类app中,都使用了feed流.例如:微信的朋友圈.今日头条的推荐页.知乎的关注页等,都是此形式. feed流是一个信息出口,想要与他人或资讯建立连接,只需要刷新这一个动作, ...
- java8 从数组获取流_从数组到流再到Java 8
java8 从数组获取流 不久前,我们将一些Eclipse插件项目升级到Java8.此后再也没有回头. 除其他事项外,使用lambda和streams API ,过滤,映射和查找集合中的元素变得更加容 ...
- java文件边读边写_[Java教程]node.js 利用流实现读写同步,边读边写
[Java教程]node.js 利用流实现读写同步,边读边写 0 2017-09-10 13:00:14 //10个数 10个字节,每次读4b,写1blet fs=require("fs&q ...
- java抓取网页标题内容_[Java教程]java 网页页面抓取标题和正文
[Java教程]java 网页页面抓取标题和正文 0 2014-07-10 09:01:30 import java.io.BufferedReader;import java.io.IOExcept ...
- java期末判断题题库_(java期末考试选择题题库.doc
(java期末考试选择题题库 1.分析以下程序: 1)public class x{ 2)public static void main(String[]args){ 3)String ol=new ...
- Java格式化日期用斜杠_[java工具类01]__构建格式化输出日期和时间的工具类
在之前的学习中,我写过一篇关于字符串格式化的,就主要设计到了时间以及日期的各种格式化显示的设置,其主要时通过String类的fomat()方法实现的. 我们可以通过使用不同的转换符来实现格式化显示不同 ...
- java中table是什么标签_[Java教程]javascript格式化table标签内容
[Java教程]javascript格式化table标签内容 0 2015-07-12 20:00:08 项目中遇到这样的需求,一大段文章正文的html代码在手机中显示不全,原因是由于其它有table ...
- java技术的核心是哪个_[JAVA]《Java 核心技术》(一)
1. unicode编码表 utf-8和unicode的互换问题 2. subString(a,b) 获得 [a,b-1]的子串 3. 易犯错误,java没有引用传递 4. == 比较 ...
最新文章
- java 对象 jvm生命_JVM对象的生命周期
- 2019年的第三场LiveVideoStackCon有何不同?
- [PAT乙级]1007 素数对猜想
- 在Linux下查看环境变量
- php查看mysql最近执行过的sql_PHP获取MySQL执行sql语句的查询时间
- 计算机vfp实验小结,vfp实验1报告心得体会
- 浅谈软件需求分析中的参与者
- wps里面函数怎么使用_WPS表格中常用文本函数的用法
- Oracle数据库存储number类型数据
- 计算机本科生优秀毕业论文,本科毕业论文计算机
- c# mvc ajax txt auto,ASP.Net MVC和复制div中的自我AJAX更新局部视图/控制器
- 7-3 小孩子才做选择,大人全都要 (10 分)
- C++中关于数据小数点,取整的方法
- php中文拼音模糊,两种php中文字符转拼音问题解决方法
- Win10 虚拟桌面的使用
- Flutter时间转换工具类
- Password verification failed
- JSP基本语法、3个编译指令、7个动作指令、9个内置对象
- Android新闻客户端实训-Day1类Day2接口基操
- 2018CCPC吉林赛区 | 部分题解 (HDU6555 HDU6556 HDU6559 HDU6561)
热门文章
- C++17基本教程 第6讲 数组 (tcy)
- 哥伦比亚大学 自然语言处理 公开课 授课讲稿 翻译(二)
- ThinkPad SL410 安装XP系统需要注意的地方
- P1607 [USACO09FEB]Fair Shuttle G
- 程序员看看笑话幽默有主减压,整理了一些不错的小幽默分享出来
- xdebug linux,linux下配置xdebug
- 超强AI对话系统ChatGPT不完全案例指南
- STM32项目-STM32智能小车-电子设计大赛-STM32cubemx-STM32f103c8t6STM32串口通信-
- PHP标签的模板技术
- Deep SDF 、NeuS学习