什么是IO流?

这里是修真院后端小课堂,每篇分享文从

【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】

八个方面深度解析后端知识/技能,本篇分享的是:

什么是IO流?

大家好,我是IT修真院北京分院第27期的JAVA学员,一枚正直纯洁善良的java程序员。

今天给大家分享一下,修真院官网Java任务10,深度思考中的知识点———什么是IO流?

1.背景介绍

什么是流

流就是一系列的数据

当不同的介质之间有数据交互的时候,JAVA就使用流来实现。 数据源可以是文件,还可以是数据库,网络甚至是其他的程序。 比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流。 输入流: InputStream 输出流:OutputStream

文件输入流

如下代码,就建立了一个文件输入流,这个流可以用来把数据从硬盘的文件,读取到JVM(内存)。 目前代码只是建立了流,还没有开始读取。

package stream;                        
import java.io.File;import java.io.FileInputStream;import java.io.IOException;                        
public class TestStream {   public static void main(String[] args) {     try {
         File f = new File("d:/lol.txt");          // 创建基于文件的输入流
         FileInputStream fis = new FileInputStream(f);         // 通过这个输入流,就可以把数据从硬盘,读取到Java的虚拟机中来,也就是读取到内存中
         } catch (IOException e) {            // TODO Auto-generated catch block
             e.printStackTrace();
          }
                        
       }
  }

--如图:

666

 

2.知识剖析

字节流

InputStream字节输入流 OutputStream字节输出流 用于以字节的形式读取和写入数据

ASCII码 概念

所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放。 比如A就对应的数字65,a对应的数字97. 不同的字母和符号对应不同的数字,就是一张码表。 ASCII是这样的一种码表。 只包含简单的英文字母,符号,数字等。 不包含中文,德文,俄语等复杂的。

<table>
<tr>
<td>字符</td>
<td>十进制数字</td>
<td>十六进制数字</td>
</tr>
<tr>
<td>!</td>
<td>33</td>
<td>21</td>
</tr>
<tr>
<td>"</td>
<td>34</td>
<td>22</td>
</tr>
<tr>
<td>#</td>
<td>35</td>
<td>23</td>
</tr>
<tr>
<td>$</td>
<td>36</td>
<td>24</td>
</tr>
<tr>
<td>%</td>
<td>37</td>
<td>25</td>
</tr>
<tr>
<td>&</td>
<td>38</td>
<td>26</td>
</tr>
<tr>
<td>'</td>
<td>39</td>
<td>27</td>
</tr>
<tr>
<td>(</td>
<td>40</td>
<td>28</td>
</tr>
<tr>
<td>)</td>
<td>41</td>
<td>29</td>
</tr>
<tr>
<td>*</td>
<td>42</td>
<td>2A</td>
</tr>
<tr>
<td>+</td>
<td>43</td>
<td>2B</td>
</tr>
<tr>
<td>,</td>
<td>44</td>
<td>2C</td>
</tr>
<tr>
<td>-</td>
<td>45</td>
<td>2D</td>
</tr>
<tr>
<td>.</td>
<td>46</td>
<td>2E</td>
</tr>
<tr>
<td>/</td>
<td>47</td>
<td>2F</td>
</tr>
<tr>
<td>0</td>
<td>48</td>
<td>30</td>
</tr>
<tr>
<td>1</td>
<td>49</td>
<td>31</td>
</tr>
<tr>
<td>2</td>
<td>50</td>
<td>32</td>
</tr>
<tr>
<td>3</td>
<td>51</td>
<td>33</td>
</tr>
<tr>
<td>4</td>
<td>52</td>
<td>34</td>
</tr>
<tr>
<td>5</td>
<td>53</td>
<td>35</td>
</tr>
<tr>
<td>6</td>
<td>54</td>
<td>36</td>
</tr>
<tr>
<td>7</td>
<td>55</td>
<td>37</td>
</tr>
<tr>
<td>8</td>
<td>56</td>
<td>38</td>
</tr>
<tr>
<td>9</td>
<td>57</td>
<td>39</td>
</tr>
<tr>
<td>:</td>
<td>58</td>
<td>3A</td>
</tr>
<tr>
<td>;</td>
<td>59</td>
<td>3B</td>
</tr>
<tr>
<td><</td>
<td>60</td>
<td>3C</td>
</tr>
<tr>
<td>=</td>
<td>61</td>
<td>3D</td>
</tr>
<tr>
<td>></td>
<td>62</td>
<td>3E</td>
</tr>
<tr>
<td>@</td>
<td>64</td>
<td>40</td>
</tr>
<tr>
<td>A</td>
<td>65</td>
<td>41</td>
</tr>
<tr>
<td>B</td>
<td>66</td>
<td>42</td>
</tr>
<tr>
<td>C</td>
<td>67</td>
<td>43</td>
</tr>
<tr>
<td>D</td>
<td>68</td>
<td>44</td>
</tr>
<tr>
<td>E</td>
<td>69</td>
<td>45</td>
</tr>
<tr>
<td>F</td>
<td>70</td>
<td>46</td>
</tr>
<tr>
<td>G</td>
<td>71</td>
<td>47</td>
</tr>
<tr>
<td>H</td>
<td>72</td>
<td>48</td>
</tr>
<tr>
<td>I</td>
<td>73</td>
<td>49</td>
</tr>
<tr>
<td>J</td>
<td>74</td>
<td>4A</td>
</tr>
<tr>
<td>K</td>
<td>75</td>
<td>4B</td>
</tr>
<tr>
<td>L</td>
<td>76</td>
<td>4C</td>
</tr>
<tr>
<td>M</td>
<td>77</td>
<td>4D</td>
</tr>
<tr>
<td>N</td>
<td>78</td>
<td>4E</td>
</tr>
<tr>
<td>O</td>
<td>79</td>
<td>4F</td>
</tr>
<tr>
<td>P</td>
<td>80</td>
<td>50</td>
</tr>
<tr>
<td>Q</td>
<td>81</td>
<td>51</td>
</tr>
<tr>
<td>R</td>
<td>82</td>
<td>52</td>
</tr>
<tr>
<td>S</td>
<td>83</td>
<td>53</td>
</tr>
<tr>
<td>T</td>
<td>84</td>
<td>54</td>
</tr>
<tr>
<td>U</td>
<td>85</td>
<td>55</td>
</tr>
<tr>
<td>V</td>
<td>86</td>
<td>56</td>
</tr>
<tr>
<td>W</td>
<td>87</td>
<td>57</td>
</tr>
<tr>
<td>X</td>
<td>88</td>
<td>58</td>
</tr>
<tr>
<td>Y</td>
<td>89</td>
<td>59</td>
</tr>
<tr>
<td>Z</td>
<td>90</td>
<td>5A</td>
</tr>
<tr>
<td>[</td>
<td>91</td>
<td>5B</td>
</tr>
<tr>
<td>\</td>
<td>92</td>
<td>5C</td>
</tr>
<tr>
<td>]</td>
<td>93</td>
<td>5D</td>
</tr>
<tr>
<td>^</td>
<td>94</td>
<td>5E</td>
</tr>
<tr>
<td>_</td>
<td>95</td>
<td>5F</td>
</tr>
<tr>
<td>`</td>
<td>96</td>
<td>60</td>
</tr>
<tr>
<td>a</td>
<td>97</td>
<td>61</td>
</tr>
<tr>
<td>b</td>
<td>98</td>
<td>62</td>
</tr>
<tr>
<td>c</td>
<td>99</td>
<td>63</td>
</tr>
<tr>
<td>d</td>
<td>100</td>
<td>64</td>
</tr>
<tr>
<td>e</td>
<td>101</td>
<td>65</td>
</tr>
<tr>
<td>f</td>
<td>102</td>
<td>66</td>
</tr>
<tr>
<td>g</td>
<td>103</td>
<td>67</td>
</tr>
<tr>
<td>h</td>
<td>104</td>
<td>68</td>
</tr>
<tr>
<td>i</td>
<td>105</td>
<td>69</td>
</tr>
<tr>
<td>j</td>
<td>106</td>
<td>6A</td>
</tr>
<tr>
<td>k</td>
<td>107</td>
<td>6B</td>
</tr>
<tr>
<td>l</td>
<td>108</td>
<td>6C</td>
</tr>
<tr>
<td>m</td>
<td>109</td>
<td>6D</td>
</tr>
<tr>
<td>n</td>
<td>110</td>
<td>6E</td>
</tr>
<tr>
<td>o</td>
<td>111</td>
<td>6F</td>
</tr>
<tr>
<td>p</td>
<td>112</td>
<td>70</td>
</tr>
<tr>
<td>q</td>
<td>113</td>
<td>71</td>
</tr>
<tr>
<td>r</td>
<td>114</td>
<td>72</td>
</tr>
<tr>
<td>s</td>
<td>115</td>
<td>73</td>
</tr>
<tr>
<td>t</td>
<td>116</td>
<td>74</td>
</tr>
<tr>
<td>u</td>
<td>117</td>
<td>75</td>
</tr>
<tr>
<td>v</td>
<td>118</td>
<td>76</td>
</tr>
<tr>
<td>w</td>
<td>119</td>
<td>77</td>
</tr>
<tr>
<td>x</td>
<td>120</td>
<td>78</td>
</tr>
<tr>
<td>y</td>
<td>121</td>
<td>79</td>
</tr>
<tr>
<td>z</td>
<td>122</td>
<td>7A</td>
</tr>
<tr>
<td>{</td>
<td>123</td>
<td>7B</td>
</tr>
<tr>
<td>|</td>
<td>124</td>
<td>7C</td>
</tr>
<tr>
<td>}</td>
<td>125</td>
<td>7D</td>
</tr>
<tr>
<td>~</td>
<td>126</td>
<td>7E</td>
</tr>

--

以字节流的形式读取文件内容

InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。 FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取

以字节流的形式向文件写入数据

OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。 FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据 注: 如果文件d:/lol2.txt不存在,写出操作会自动创建该文件。 但是如果是文件 d:/xyz/lol2.txt,而目录xyz又不存在,会抛出异常

数据流

DataInputStream 数据输入流 DataOutputStream 数据输出流

直接进行字符串的读写

使用数据流的writeUTF()和readUTF() 可以进行数据的格式化顺序读写 如本例,通过DataOutputStream 向文件顺序写出 布尔值,整数和字符串。 然后再通过DataInputStream 顺序读入这些数据。 注: 要用DataInputStream 读取一个文件,这个文件必须是由DataOutputStream 写出的,否则会出现EOFException,因为DataOutputStream 在写出的时候会做一些特殊标记,只有DataInputStream 才能成功的读取。

对象流

对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘 一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口

序列化一个对象

把一个对象序列化有一个前提是:这个对象的类,必须实现了Serializable接口

字符流

Reader字符输入流 Writer字符输出流 专门用于字符的形式读取和写入数据

使用字符流读取文件

FileReader 是Reader子类,以FileReader 为例进行文件读取

使用字符流把字符串写入到文件

FileWriter 是Writer的子类,以FileWriter 为例把字符串写入到文件

缓存流

以介质是硬盘为例,字节流和字符流的弊端: 在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。 为了解决以上弊端,采用缓存流。 缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。 就好比吃饭,不用缓存就是每吃一口都到锅里去铲。用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲 缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作。

使用缓存流读取数据

缓存字符输入流 BufferedReader 可以一次读取一行数

使用缓存流写出数据

PrintWriter 缓存字符输出流, 可以一次写出一行数据

FLUSH方法

有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush

 

3.常见问题

如何关闭流

所有的流,无论是输入流还是输出流,使用完毕之后,都应该关闭。 如果不关闭,会产生对资源占用的浪费。 当量比较大的时候,会影响到业务的正常开展

4.解决方案

  • 在try中关闭

在try的作用域里关闭文件输入流,在前面的示例中都是使用这种方式,这样做有一个弊端; 如果文件不存在,或者读取的时候出现问题而抛出异常,那么就不会执行这一行关闭流的代码,存在巨大的资源占用隐患。 不推荐使用

  • 在finally中关闭

这是标准的关闭流的方式 1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally. 2. 在finally关闭之前,要先判断该引用是否为空 3. 关闭的时候,需要再一次进行try catch处理 这是标准的严谨的关闭流的方式,但是看上去很繁琐,所以写不重要的或者测试代码的时候,都会采用上面的有隐患try的方式,因为不麻烦

  • 使用try()的方式

把流定义在try()里,try,catch或者finally结束的时候,会自动关闭 这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术 所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try,catch,finally结束的时候自动关闭,回收相关资源

5.编码实战

详见视频

6.扩展思考

SYSTEM.IN使用

System.out 是常用的在控制台输出数据的 System.in 可以从控制台输入数据

使用SYSTEM.IN.READ虽然可以读取数据,但是很不方便。使用SCANNER就可以逐行读取了

7.    参考文献

how2j.cn: http://how2j.cn/k/io/io-system-in/352.html#nowhere

8.    更多讨论

Q1:io流的存储位置和流向问题? A1:IO流一般是以内存为基准,我们的IO流最开始是在jvm中,然后流向硬盘。

Q2:IO流传输时,是以文件为单位传输,还是以文件内字节或字符依次传输? A2:两种情况都有,只是进行文件传输时候,会产生垃圾数据,锟斤拷

Q3:中文问题? A3:工作后经常接触的编码方式有如下几种: ISO-8859-1 ASCII 数字和西欧字母 GBK GB2312 BIG5 中文 UNICODE (统一码,万国码) 其中 ISO-8859-1 包含 ASCII GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。 UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

PPT链接 视频链接

更多内容,可以加入IT交流群565734203与大家一起讨论交流

这里是技能树·IT修真院:,初学者转行到互联网的聚集地

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 连接 连接池产生原因 连接池实现原理 小结 TEMPERANCE:Eat not to dullness;drink not to elevation.节制
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。-- 毕玄 1. 命名风格 【书摘】类名用 UpperCamelC
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个人在用”。哪怕只是throw了一个新的Exception。哈哈,这是我犯的错误。一、接口和抽象类类,即一个对象。先抽象类,就是抽象出类的基础部分,即抽象基类(抽象类)。官方定义让人费解,但是记忆方法是也不错的 —包含抽象方法的类叫做抽象类。接口
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket一、引子文件,作为常见的数据源。关于操作文件的字节流就是 —FileInputStream&amp;FileOutputStream。
作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节。交流QQ群:【编程之美 365234583】http://qm.qq.com/cgi-bin/qm/qr?k=FhFAoaWwjP29_Aonqz
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程与多线程 线程是什么? 线程(Thread)是一个对象(Object)。用来干什么?Java 线程(也称 JVM 线程)是 Java 进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。 Ja
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket在面向对象编程中,编程人员应该在意“资源”。比如?1String hello = &quot;hello&quot;; 在代码中,我们
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 《程序兵法:Java String 源码的排序算法(一)》 文章工程:* JDK 1.8* 工程名:algorithm-core-le
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 一、父子类变量名相同会咋样? 有个小故事,今天群里面有个人问下面如图输出什么? 我回答:60。但这是错的,答案结果是 40 。我知错能改,然后说了下父子类变
作者:泥瓦匠 出处:https://www.bysocket.com/2021-10-26/mac-create-files-from-the-root-directory.html Mac 操作系统挺适合开发者进行写代码,最近碰到了一个问题,问题是如何在 macOS 根目录创建文件夹。不同的 ma
作者:李强强上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算。这一讲,泥瓦匠带你走进Java中的进制详解。一、引子在Java世界里,99%的工作都是处理这高层。那么二进制,字节码这些会在哪里用到呢?自问自答:在跨平台的时候,就凸显神功了。比如说文件读写,数据通信,还
1 线程中断 1.1 什么是线程中断? 线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 方法,使得该线程中断标志位属性改变。 深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want需求 项目在设计表的时候,要处理并发多的一些数据,类似订单号不能重复,要保持唯一。原本以为来个时间戳,精确到毫秒应该不错了。后来觉得是错了,测试环境下很多一
纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 加微信:bysocket01
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want.文章Points:1、介绍RESTful架构风格2、Spring配置CXF3、三层初设计,实现WebService接口层4、撰写HTTPClient 客户
Writer :BYSocket(泥沙砖瓦浆木匠)什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道“就一个回调…”。此时千万个草泥马飞奔而过(逃哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉。不妨总结总结。一、什么是回调回调,回调。要先有调用,才有调用者和被调用者之间的回调。所以在百
Writer :BYSocket(泥沙砖瓦浆木匠)一、什么大小端?大小端在计算机业界,Endian表示数据在存储器中的存放顺序。百度百科如下叙述之:大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加
What is a programming language? Before introducing compilation and decompilation, let&#39;s briefly introduce the Programming Language. Programming la
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket泥瓦匠喜欢Java,文章总是扯扯Java。 I/O 基础,就是二进制,也就是Bit。一、Bit与二进制什么是Bit(位)呢?位是CPU
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocket一、前言 泥瓦匠最近被项目搞的天昏地暗。发现有些要给自己一些目标,关于技术的目标:专注很重要。专注Java 基础 + H5(学习) 其他操作系统,算法,数据结构当成课外书博览。有时候,就是那样你越是专注方面越