java基础io流——OutputStream和InputStream的故事(温故知新)

java基础io流——OutputStream和InputStream的故事(温故知新)io 流概述 IO 流用来处理设备之间的数据传输 上传文件和下载文件 Java 对数据的操作是通过流的方式 Java 用于操作流的对象都在 IO 包中 IO 流分类按照数据流向输入流读入数据输出流写出数据按照数据类型字节流字符流什么情况下使用哪种流呢 如果数据所在的文件通过 windows 自带的记事本打开并能读懂里面的内容 就用字符流 其他用字节流 如果你什么都

io流概述:

IO流用来处理设备之间的数据传输,上传文件和下载文件,Java对数据的操作是通过流的方式,Java用于操作流的对象都在IO包中。

IO流分类

按照数据流向

输入流 读入数据

输出流 写出数据

按照数据类型

字节流

字符流

什么情况下使用哪种流呢?

如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流,其他用字节流。

如果你什么都不知道,就用字节流。

IO流常用基类

字节流的抽象基类:

InputStream ,OutputStream。

字符流的抽象基类:

Reader , Writer。

注:
由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。






OutputStream的子类FileOutputStream

构造方法:

FileOutputStream(File file)

FileOutputStream(String name)

推荐第二种构造方法:

FileOutputStream outputStream = new FileOutputStream("a.txt"); 

创建字节输出流对象了做了几件事情:

A:调用系统功能去创建文件 B:创建outputStream对象 C:把foutputStream对象指向这个文件 

通过字节输出流写出数据到文本

public void write(int b) public void write(byte[] b) public void write(byte[] b,int off,int len) 

从方法中可看出,只能通过字节写出

outputStream.write("hello".getBytes()); 文本中出现hello outputStream.write(96) //文本中出现 a byte[] bys={97,98,99,100,101}; outputStream.write(bys,1,3); 文本中出现bcd 

如此写出,文本中数据不会换行,不会追加,每次写出都是覆盖原来。

追加:
FileOutputStream outputStream = new FileOutputStream("a.txt",true); //第二个参数true设置为可追加。 
换行 \n\r :
for (int i = 0; i <5 ; i++) { outputStream.write("hello".getBytes()); outputStream.write("\n\r".getBytes()); } 

注:用完流一定要记得关闭。

outputStream.close(); 

完整示例:

package io2; import java.io.FileOutputStream; import java.io.IOException; / * new FileOutputStream("a.txt",true); 第二个参数true,设置为写入的数据拼接在尾部 * \n\r 换行 * write(bys,1,3); 写入字节数组 */ public class out { public static void main(String args[]){ FileOutputStream outputStream = null; try { //FileOutputStream fos = new FileOutputStream(file); outputStream = new FileOutputStream("a.txt",true); /* * 创建字节输出流对象了做了几件事情: * A:调用系统功能去创建文件 * B:创建outputStream对象 * C:把foutputStream对象指向这个文件 */ // for (int i = 0; i <5 ; i++) { // outputStream.write("hello".getBytes()); // outputStream.write("\n\r".getBytes()); // } byte[] bys={97,98,99,100,101}; outputStream.write(bys,1,3); } catch (IOException e) { e.printStackTrace(); } finally { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } 

InputStream的子类FileInputStream

FileInputStream的构造方法

FileInputStream(File file) FileInputStream(String name) 

推荐第二种构造方法:

 FileInputStream inputStream = new FileInputStream("a.txt"); 

把刚才写的数据现在读取到控制台:

public int read() public int read(byte[] b) 

第一个read是读一个字节,第二个read是读一个字节数组。

//读一个字节 int by = 0; while ((by=inputStream.read())!=-1){ System.out.println((char)by); } 

读到没数据了就返回-1,这个用来判断是否读完。

//读一个字节数组,一般是1024大小 int len = 0 ; byte[] bys = new byte[1024]; while ((len = inputStream.read(bys)) != -1) { System.out.println(new String(bys,0,len)); } 

两个read的返回值略有不同,read()返回读取的字节,读到末尾返回-1,read(byte[] b)返回的是读到的字节个数,读到的字节放在了bytes字节数组里,读到末尾没数据了返回-1。

两种读取方式图解:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yv0oyKLy-19)(http://p5kllyq5h.bkt.clouddn.com/.jpg)]

同样的用完了流,也要及时的关闭,以防占用内存。

inputStream.close(); 

完整示例:

建议以字节数组的方式读取数据。

package io2; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; / * Create by stefan * Date on 2018-05-27 23:00 * Convertion over Configuration! */ public class input2 { public static void main(String args[]){ FileInputStream inputStream = null; try { inputStream = new FileInputStream("a.txt"); // byte[] bys = new byte[4]; // int len = inputStream.read(bys); // System.out.println(new String(bys)); //bcd // System.out.println(len); //3 // System.out.println(inputStream.read(bys)); //-1 int len = 0 ; byte[] bys = new byte[1024]; while ((len = inputStream.read(bys)) != -1) { System.out.println(new String(bys,0,len)); } / * public String(byte bytes[]) { this(bytes, 0, bytes.length); } */ } catch (IOException e) { e.printStackTrace(); }finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } 

字节流复制文件

利用输入流读取一个文件里的字节,再利用输出流将读取到的字节写出到另一个文件中(不存在会自动创建)

package io2; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; / * Create by stefan * Date on 2018-05-27 23:19 * Convertion over Configuration! */ public class copy { public static void main(String args[]) throws IOException { FileInputStream inputStream = new FileInputStream("E:\\huge1.jpg"); FileOutputStream outputStream = new FileOutputStream("E:\\古月.jpg"); byte[] bytes = new byte[1024]; int len = 0; while ((len=inputStream.read(bytes)) != -1) { outputStream.write(bytes,0,len); } inputStream.close(); outputStream.close(); } } 

注:复制文本、图片、mp3、视频等的方式一样。

字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果。

java本身在设计的时候,也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流。

字节缓冲输出流 BufferedOutputStream 字节缓冲输入流 BufferedInputStream 

BufferedOutputStream

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt",true)); bos.write("hello world".getBytes()); bos.close(); 

BufferedInputStream

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt")); byte[] bytes = new byte[1024]; int len = 0; while ((len=bis.read(bytes)) != -1) { System.out.println(new String(bytes,0,len)); } bis.close(); 

注:

  • 成员方法与字节流基本一样,字节缓冲流的作用就是提高输入输出的效率。
  • 构造方法可以指定缓冲区的大小,但是我们一般用不上,因为默认缓冲区大小就足够了。
  • 为什么不传递一个具体的文件或者文件路径,而是传递一个OutputStream对象呢?原因很简单,字节缓冲区流仅仅提供缓冲区,为高效而设计的。但是呢,真正的读写操作还得靠基本的流对象实现。

复制文件的升级:

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\modern-java.pdf")); BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\汤包\\慕课大巴\\modern-java.pdf")); int len = 0; byte[] bytes =new byte[1024]; while ((len=bis.read(bytes)) != -1) { bos.write(bytes,0,len); } bis.close(); bos.close(); 

测试:四种复制文件的效率高低

package io2; import java.io.*; / * * 测试复制的时间 * Create by stefan * Date on 2018-05-28 10:28 * Convertion over Configuration! */ public class copy2 { //一个字节一个字节的复制,耗时22697毫秒 public static void fun() throws IOException { FileInputStream fis = new FileInputStream("F:\\汤包\\慕课大巴\\modern-java.pdf"); FileOutputStream fos = new FileOutputStream("E:\\modern-java.pdf"); int by = 0; while ((by=fis.read()) != -1) { fos.write(by); } fis.close(); fos.close(); } //1024字节数组复制 耗时63毫秒 public static void fun1() throws IOException { FileInputStream fis = new FileInputStream("F:\\汤包\\慕课大巴\\modern-java.pdf"); FileOutputStream fos = new FileOutputStream("E:\\modern-java.pdf"); int len = 0; byte[] bytes =new byte[1024]; while ((len=fis.read(bytes)) != -1) { fos.write(bytes,0,len); } fis.close(); fos.close(); } // 一个字节一个字节复制,但是用了缓冲流 耗时64毫秒 public static void fun2() throws IOException { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\modern-java.pdf")); BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\汤包\\慕课大巴\\modern-java.pdf")); int by = 0; while ((by=bis.read()) != -1) { bos.write(by); } bis.close(); bos.close(); } // 1024字节数组复制并用了缓冲流 耗时7毫秒 public static void fun3() throws IOException { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\modern-java.pdf")); BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\汤包\\慕课大巴\\modern-java.pdf")); int len = 0; byte[] bytes =new byte[1024]; while ((len=bis.read(bytes)) != -1) { bos.write(bytes,0,len); } bis.close(); bos.close(); } public static void main(String args[]) throws IOException { long t1 = System.currentTimeMillis(); fun3(); long t2 = System.currentTimeMillis(); System.out.println(t2-t1); } } 

经测试结果显示:
1024字节数组复制并用了缓冲流 的方式效率最高。

以上是本人学习笔记整理,重温java经典,欢迎各位同道中人批评指正。

源码码云地址:
https://gitee.com/stefanpy/java

梦回io流完整目录:

java基础io流——File告白(重温经典)

java基础io流——OutputStream和InputStream的故事(温故知新)

java基础io流——字符流的变革(深入浅出)

java基础io流——配角也风流(不求甚解)

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/199864.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 下午12:02
下一篇 2026年3月20日 下午12:02


相关推荐

  • overflow:hidden作用能治住塌陷_html溢出隐藏代码

    overflow:hidden作用能治住塌陷_html溢出隐藏代码一.overflow:hidden溢出隐藏给一个元素中设置overflow:hidden,那么该元素的内容若超出了给定的宽度和高度属性,那么超出的部分将会被隐藏,不占位。/*css样式*/<styletype=”text/css”>div{width:150px;height:60px;background:skyblue; overflo…

    2025年5月27日
    4
  • L3-001 凑零钱(回溯和0-1背包)[通俗易懂]

    L3-001 凑零钱(回溯和0-1背包)[通俗易懂]韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩梅梅手边有 10​4​​ 枚来自各个星球的硬币,需要请你帮她盘算一下,是否可能精确凑出要付的款额。输入格式:输入第一行给出两个正整数:N(≤10​4​​ )是硬币的总个数,M(≤10​2​​ )是韩梅梅要付的款额。第二行给出 N 枚硬币的正整数面值。数字间以空格分隔。输出格式:在一行中输出硬币的面值 V​1​​ ≤V​2​​ ≤⋯≤V​k

    2022年8月8日
    7
  • sprintf函数的用法linux,sprintf函数用法解析

    sprintf函数的用法linux,sprintf函数用法解析shortsi=-1;sprintf(s,”%04X”,si);产生“FFFFFFFF”,怎么回事?因为spritnf是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个“%X”就能得知当初函数调用前参数压栈时被压进来的到底是个4字节的整数还是个2字节的短整数,所以采取了统一4字节的处理方式,导致参数压栈时做了符号扩展,扩展成了32位的整数…

    2022年6月16日
    45
  • Cursor安装使用教程(超详细)

    Cursor安装使用教程(超详细)

    2026年3月16日
    2
  • 图像处理—-lena图像的由来「建议收藏」

    图像处理—-lena图像的由来「建议收藏」作者: 邓亮来源http://kexuesongshuhui.blog.163.com/blog/static/935965672009626101158405/?163toutiao 她是让无数专家为之痴迷和痛苦的研究对象,她是充斥着枯燥数学公式的论文中最吸引眼球的光芒,翻开任何一本关于计算机图像处理的教材,你都能看到她动人的微笑。她就是雷娜(Lena),她的照片是图像处理领域使用最

    2022年6月19日
    33
  • 如何在win10上同时安装python2和python3

    如何在win10上同时安装python2和python3

    2021年10月16日
    63

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号