组团学

输入输出流(IO)

阅读 (324609)

1、IO流概述

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

2、IO流分类

按照数据流向

输入流 读入数据
输出流 写出数据

按照数据类型

字节流

字符流

3、IO流基类

字节流的抽象基类:
InputStream

​ OutputStream
字符流的抽象基类:
​ Reader

​ Writer

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

4、字节流写数据

​ OutputStream
​ FileOutputStream
​ 往一个文本文件中写一句话:”helloworld”
​ 分析发现其实更适合用字符流,但是由于字节流先出现,所以,我们考虑先使用字节流后面再讲会什么出现字符流。
​ FileOutputStream的构造方法
​ FileOutputStream(File file)
​ FileOutputStream(String name)

5、字节流写数据的方式

public void write(int b)

public void write(byte[] b)

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

案例一:

/* 步骤: A:创建字节输出流对象 B:写数据 C:释放资源 */ public static void main(String[] args) throws IOException { // 创建字节输出流对象 FileOutputStream fos = new FileOutputStream("fos.txt"); /* * 创建字节输出流对象了做了几件事情? * A:调用系统功能去创建文件 * B:创建fos对象 * C:把fos对象指向这个文件 */ //写数据 fos.write("hello,IO".getBytes()); fos.write("java".getBytes()); //释放资源 //关闭此文件输出流并释放与此流有关的所有系统资源。 fos.close(); /* * 为什么一定要close()呢? * A:让流对象变成垃圾,这样就可以被垃圾回收器回收了 * B:通知系统去释放跟该文件相关的资源 */ //fos.write("java".getBytes()); //java.io.IOException: Stream Closed }

案例二

public static void main(String[] args) throws IOException { // 创建字节输出流对象 FileOutputStream fos = new FileOutputStream("fos2.txt"); // 调用write()方法 //fos.write(97); //97 -- 底层二进制数据 -- 通过记事本打开 -- 找97对应的字符值 -- a // fos.write(57); // fos.write(55); //public void write(byte[] b):写一个字节数组 byte[] bys={97,98,99,100,101}; fos.write(bys); //public void write(byte[] b,int off,int len):写一个字节数组的一部分 fos.write(bys,1,3); //释放资源 fos.close(); }

实现数据换行

/* 不同的系统针对不同的换行符号识别是不一样的? windows:\r\n linux:\n Mac:\r */ public static void main(String[] args) throws IOException { // 创建字节输出流对象 FileOutputStream fos = new FileOutputStream("fos3.txt"); // 写数据 for (int x = 0; x < 10; x++) { fos.write(("hello" + x).getBytes()); fos.write("\r\n".getBytes());//换行 } // 释放资源 fos.close(); }

实现数据的追加

public static void main(String[] args) throws IOException { // 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。 FileOutputStream fos = new FileOutputStream("fos3.txt", true); // 写数据 for (int x = 0; x < 10; x++) { fos.write(("hello" + x).getBytes()); fos.write("\r\n".getBytes()); } // 释放资源 fos.close(); }

6、字节流写数据常见问题

创建字节输出流到底做了哪些事情?

数据写成功后,为什么要close()?

如何实现数据的换行?

如何实现数据的追加写入?

7、字节流写数据加入异常处理

加入异常处理的IO流操作

public static void main(String[] args) { //分开做异常处理 FileOutputStream fos = null; try { fos = new FileOutputStream("fos4.txt"); } catch (FileNotFoundException e) { e.printStackTrace(); } try { fos.write("java".getBytes()); } catch (IOException e) { e.printStackTrace(); } try { fos.close(); } catch (IOException e) { e.printStackTrace(); } }
public static void main(String[] args) { //一起做异常处理 try { FileOutputStream fos = new FileOutputStream("fos4.txt"); fos.write("java".getBytes()); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
public static void main(String[] args) { //改进版 //为了在finally里面能够看到该对象就必须定义到外面,为了访问不出问题,还必须给初始化值 FileOutputStream fos = null; try { fos = new FileOutputStream("fos4.txt"); fos.write("java".getBytes()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 如果fos不是null,才需要close() if (fos != null) { // 为了保证close()一定会执行,就放到这里了 try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }

8、字节流读取数据

InputStream
FileInputStream

把写的数据读取出来显示在控制台
FileInputStream的构造方法
FileInputStream(File file)
FileInputStream(String name)
FileInputStream的成员方法
public int read()
public int read(byte[] b)

9、字节流读取数据的两种方式

一次读取一个字节
一次读取一个字节数组(每次可以读取多个数据,提高了操作效率)

一次读取一个字节

public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("FileOutputStreamDemo.java"); // 调用read()方法读取数据,并把数据显示在控制台 // 第一次读取 int by = fis.read(); System.out.println(by); System.out.println((char) by); // 第二次读取 by = fis.read(); System.out.println(by); System.out.println((char) by); // 第三次读取 by = fis.read(); System.out.println(by); System.out.println((char) by); // 第四次读取 by = fis.read(); System.out.println(by); // 第五次读取 by = fis.read(); System.out.println(by); //通过测试,我们知道如果你读取的数据是-1,就说明已经读取到文件的末尾了 // 释放资源 fis.close(); }

一次读取一个字节用循环改进

public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("FileOutputStreamDemo.java"); // 调用read()方法读取数据,并把数据显示在控制台 // 用循环改进 int by = 0; // 读取,赋值,判断 while ((by = fis.read()) != -1) { System.out.print((char) by); } // 释放资源 fis.close(); }

一次读取一个字节数组

public static void main(String[] args) throws IOException { // 创建字节输入流对象 FileInputStream fis = new FileInputStream("FileOutputStreamDemo.java"); //读取数据 //定义一个字节数组 //第一次读取 byte[] bys = new byte[5]; int len = fis.read(bys); System.out.print(new String(bys, 0, len)); // 第二次读取 len = fis.read(bys); System.out.print(new String(bys, 0, len)); // 第三次读取 len = fis.read(bys); System.out.print(new String(bys, 0, len)); // 第四次读取 len = fis.read(bys); System.out.print(new String(bys, 0, len)); // 代码重复了,用循环改进 // 但是,我不知道结束条件 len = fis.read(bys); System.out.println(len); len = fis.read(bys); System.out.println(len); //如果读取到的实际长度是-1,就说明没有数据了 //数组的长度一般是1024或者1024的整数倍 byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { System.out.print(new String(bys, 0, len)); } // 释放资源 fis.close(); }

一次读取一个字节数组最终版

public static void main(String[] args) throws IOException { // 创建字节输入流对象 FileInputStream fis = new FileInputStream("FileOutputStreamDemo.java"); //数组的长度一般是1024或者1024的整数倍 byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { System.out.print(new String(bys, 0, len)); } // 释放资源 fis.close(); }

10、字节流复制数据练习

把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中

步骤:
1、封装数据源

​2、封装目的地

​3、复制数据

4、关闭资源

public static void main(String[] args) throws IOException { // 封装数据源 FileInputStream fis = new FileInputStream("a.txt"); // 封装目的地 FileOutputStream fos = new FileOutputStream("b.txt"); //复制数据 int by = 0; while ((by = fis.read()) != -1) { fos.write(by); } // 释放资源(先关谁都行) fos.close(); fis.close(); }
需要 登录 才可以提问哦