IO流02
概述
1)IO流:设备和设备之间的传输(读写)
2)分类
按流的方向分为:
输入流 --->读取数据
输出流 --->写出数据
按数据类型分为:
字节输入流:InputStream ----读数据
字节输出流:OutputStream ----写数据
字符输入流:Reader
字符输出流:Writer
3)需求:写一个文件,这个文件内容是:hello,io
分析:写这样一个文件:最常用的是使用字符流
但是字符流实在字节流之后才产生的
所以:先讲字节流中的字节输出流,后面讲字符流
A.字节输出流OutputStream
1)概述
一个抽象类,不能被实例化
使用他的对象进行写数据
现在的需求:针对的是文件:File 联想起来:FileOutputStream
对于输出流和输入流来说,他们的基类的子类的后缀名是以下形式
XXXOutputStream
XXXInputStream
XXXReader
xxxWriter
2)些数据的具体步骤:
a.创建字节输出流对象
构造方法:
public FileOutputStream(File file):指定一个File对象
public FileOutputStream(String name):直接指定文件名称(常用)
b.写数据
c.释放资源
import java.io.FileOutputStream; import java.io.IOException; public class Demo01 { public static void main(String[] args) throws IOException { /** * 创建文件字节流输出对象做了几件事情? 1)调用系统功能区创建FileOutputStream对象 2)将fos对象指向fos.txt文件 */ // 抛出异常,在这为了方便演示,在main方法上直接抛弃(后面再讲正确使用方法) FileOutputStream fos = new FileOutputStream("fos.txt"); // 写数据: // 字节流:应该写一个字节进去 fos.write("hello,io".getBytes()); fos.write("\r\n".getBytes()); // windows换行\r\n; Linux \n; Mac \r fos.write("java".getBytes()); // 释放资源 // 关闭资源 // 关闭和IO流对象有关的资源 fos.close(); // 资源已经关闭 // fos.write("java".getBytes()); // java.io.IOException: Stream Closed:如果流资源已经关闭,无须在去写了! } }
3)文件字节输出流对象中的写数据的方法
public void write(int b):写入一个字节
public void write(int b):写入一个字节
public void write(byte[] b, int index,int len):写一部分字节数组(常用)
import java.io.FileOutputStream; import java.io.IOException; public class Demo02 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("fos.txt"); // public void write(int b):写入一个字节 // fos.write(97);---->计算出二进制数据---->记事本打开之后----->找ASCII对应的字符:97 a // fos.write(55); // fos.write(57); // public void write(byte[] b):写一个字节数组 // 定义一个字节数数组 byte[] bys = { 97, 98, 99, 100, 101 }; // 写数据 // fos.write(bys); // public void write(byte[] b, int index,int len):写一部分字节数组 fos.write(bys, 1, 3); // 98 99 100 对应的ASCII表 // 关闭资源 fos.close(); } }
4)换行
针对不同的操作系统换行符号是不一样的:
windows:\r\n
Linux:\n
Mac:\r
5)追加操作
public FileOutputStream(File file, boolean append):
如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处
import java.io.FileOutputStream; import java.io.IOException; public class Demo03 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("fos.txt", true); // 写数据 for (int i = 0; i < 10; i++) { fos.write(("\r\n" + i + "hello").getBytes()); } // 释放资源 fos.close(); } }
6)正确的异常处理方式
文件字节输出流中加入异常处理(try...catch方式)
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Demo04 { public static void main(String[] args) { // 为了fos对象在finlly中能看到,所以把fos对象定义外面; FileOutputStream fos = null; try { fos = new FileOutputStream("fos"); // 写数据 fos.write("java".getBytes()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源,但是资源之前,首先判断资源对象是否为空 if (fos != null) { // 开始关闭资源 try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
7)练习
输出九九乘法表
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Demo05 { public static void main(String[] args) { FileOutputStream fos = null; try { fos = new FileOutputStream("九九乘法表"); fos.write("\t\t\t\t\t\t\t九九乘法表\r\n".getBytes()); for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { fos.write((j + "*" + i + "=" + j * i + "\t").getBytes()); } fos.write("\r\n".getBytes()); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
B.字节输入流InputStream
1)概述
创建输入流对象
读数据:通过读取文件,显示在控制台
释放资源
2)构造方法
public int read():一次读取一个字节
读取
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class Demo01 { public static void main(String[] args) { // 创建字节输入流对象 FileInputStream fis = null; try { fis = new FileInputStream("fis.txt"); // //一次读取一个字节 // int by = fis.read(); // System.out.println((char)by); // //.....要读很多次 /** * 重复都高,并且判断的结束条件读到-1,说明已经 读完了 */ int by = 0; while ((by = fis.read()) != -1) { System.out.print((char)by); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
public int read(byte[] b):一次读取一个字节数组
读取
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class Demo02 { public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("fis.txt"); // 读取数据:给定字节数组的长度是1024或者1024的倍数 byte[] bys = new byte[1024]; // 定义长度 int len = 0; while ((len = fis.read(bys)) != -1) { // 不能直接输出(new String(bys) // 要从0到len System.out.print(new String(bys, 0, len)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3)关于汉子
读取汉子的话,汉子不能处在数组长度的界限上,否则汉子会成乱码
一个汉字占两个字节,但要设定三个长度
例如(你好吗) new byte[n] n = 3 || n >= 6读取正常
若(a你好吗) new byte[n] n >= 7读取正常
4)练习
读取九九乘法表
"九九乘法表"这五个字肯定在1024范围内,所以字节数组长度正常设置就行
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class Demo03 { public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("九九乘法表.txt"); byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { System.out.print(new String(bys, 0, len)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }