JavaSE学习笔记(九)IO流_part1

本文详细介绍了Java中的IO流概念及分类,包括字节流与字符流的输入输出,并提供了FileInputStream、FileOutputStream、FileReader与FileWriter的具体用法示例。
摘要由CSDN通过智能技术生成

1 概述

  • I表示intput,把硬盘文件中的数据读入到内存的过程,称之输入,负责
  • O表示output,把内存中的数据写出到硬盘文件的过程,称之输出,负责

总结四大流:

  • 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流称为字节输入流。
  • 字节输出流:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件或者网络介质中去的流称为字节输出流。
  • 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流称为字符输入流。
  • 字符输出流:以内存为基准,把内存中的数据以字符的形式写出到磁盘文件或者网络介质中去的流称为字符输出流。

IO流体系结构
IO流体系结构

2 FileInputStream:文件字节输入流

  • 作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去
构造器说明
public FileInputStream​(File file)创建字节输入流管道与源文件对象接通
public FileInputStream​(String pathname)创建字节输入流管道与源文件路径接通
// 创建一个文件字节输入流管道与源文件接通。
InputStream is = new FileInputStream(new File("fileinputstream\\data.txt"));
// 简化写法
InputStream is = new FileInputStream("fileinputstream\\data.txt");

方法名称说明
public int read()每次读取一个字节返回,如果字节已经没有可读的返回-1
// 读取一个字节返回 (每次读取一滴水)
int b1 = is.read();
System.out.println((char)b1);

int b2 = is.read();
System.out.println((char)b2);

int b3 = is.read();
System.out.println((char)b3);

int b4 = is.read(); // 读取完毕返回-1
System.out.println(b4);

// 使用循环改进
int b;
while (( b = is.read() ) != -1){
    System.out.print((char) b);
    }

存在问题:性能较慢、读取中文字符输出无法避免乱码问题(一个中文字符占2-3个字节)


方法名称说明
public int read(byte[] buffer)每次读取一个字节数组返回,如果字节已经没有可读的返回-1
// 定义一个字节数组,用于读取字节数组
byte[] buffer = new byte[3]; // 3B
int len = is.read(buffer);
System.out.println("读取了几个字节:" + len);
String rs = new String(buffer);
System.out.println(rs);

int len1 = is.read(buffer);
System.out.println("读取了几个字节:" + len1);
String rs1 = new String(buffer);
System.out.println(rs1);
// buffer = [a b c]

// buffer = [a b c]  ==>  [c d c]
int len2 = is.read(buffer);
System.out.println("读取了几个字节:" + len2);
// 读取多少倒出多少
String rs2 = new String(buffer,0 ,len2);
System.out.println(rs2);

int len3 = is.read(buffer);
System.out.println(len3); // 读取完毕返回-1

// 改进使用循环,每次读取一个字节数组
byte[] buffer = new byte[3];
int len; // 记录每次读取的字节数。
while ((len = is.read(buffer)) != -1) {
    // 读取多少倒出多少
    System.out.print(new String(buffer, 0 , len));
}

读取的性能得到了提升
依旧无法避免读取中文字符输出乱码问题


方法名称说明
public byte[] readAllBytes() throws IOException直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回
public static void main(String[] args) throws Exception {
// 1、创建一个文件字节输入流管道与源文件接通
File f = new File("fileinputstream\\data.txt");
InputStream is = new FileInputStream(f);

// 2、定义一个字节数组与文件的大小刚刚一样大。
byte[] buffer = new byte[(int) f.length()];
int len = is.read(buffer);
System.out.println("读取了多少个字节:" + len);
System.out.println("文件大小:" + f.length());
System.out.println(new String(buffer));

// 读取全部字节数组
byte[] buffer = is.readAllBytes();
System.out.println(new String(buffer));
    }

如果文件过大,字节数组可能引起内存溢出
但能解决读取中文字符乱码问题

3 FileOutputStream:文件字节输出流

  • 作用:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去的流
构造器说明
public FileOutputStream​(File file)创建字节输出流管道与源文件对象接通
public FileOutputStream​(File file,boolean append)创建字节输出流管道与源文件对象接通,可追加数据
public FileOutputStream​(String filepath)创建字节输出流管道与源文件路径接通
public FileOutputStream​(String filepath,boolean append)创建字节输出流管道与源文件路径接通,可追加数据
OutputStream os = new FileOutputStream("fileinputstream\\data.txt" , true); // 追加数据管道
OutputStream os = new FileOutputStream("fileinputstream\\data.txt"); // 先清空之前的数据,写新数据进入

方法名称说明
public void write(int a)写一个字节出去
public void write(byte[] buffer)写一个字节数组出去
public void write(byte[] buffer , int pos , int len)写一个字节数组的一部分出去
flush()刷新流,还可以继续写数据
close()关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据
// 写数据出去
// a.public void write(int a):写一个字节出去
os.write('a');
os.write(98); //b
os.write("\r\n".getBytes()); // 换行

// b.public void write(byte[] buffer):写一个字节数组出去。
byte[] buffer = {'a' , 97, 98, 99}; // aabc
os.write(buffer);
os.write("\r\n".getBytes()); // 换行

byte[] buffer2 = "我是方佬肆".getBytes();
// byte[] buffer2 = "我是方佬肆".getBytes("GBK");
os.write(buffer2);
os.write("\r\n".getBytes()); // 换行


// c. public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去。
byte[] buffer3 = {'a',97, 98, 99};
os.write(buffer3, 0 , 3);
os.write("\r\n".getBytes()); // 换行

os.flush(); // 写数据必须,刷新数据 可以继续使用流
os.close(); // 释放资源,包含了刷新的!关闭后流不可以使用了

示例:拷贝文件

try {
    // 1、创建一个字节输入流管道与原视频接通
    InputStream is = new FileInputStream("fileinputstream\\data.txt");

    // 2、创建一个字节输出流管道与目标文件接通
    OutputStream os = new FileOutputStream("fileinputstream\\data2.txt");

    // 3、定义一个字节数组转移数据
    byte[] buffer = new byte[1024];
    int len; // 记录每次读取的字节数。
    while ((len = is.read(buffer)) != -1){
        os.write(buffer, 0 , len);
    	}
    System.out.println("复制完成了!");

    // 4、关闭流。
    os.close();
    is.close();
	} catch (Exception e){
    	e.printStackTrace();
}

4 FileReader:文件字符输入流

  • 作用:以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去

读取中文输出,字符流更合适,因为其最小单位是按照单个字符读取的

构造器说明
public FileReader​(File file)创建字符输入流管道与源文件对象接通
public FileReader​(String pathname)创建字符输入流管道与源文件路径接通
// 创建一个文件字节输入流管道与源文件接通。
Reader fr = new FileReader(new File("fileinputstream\\data.txt"));
// 简化写法
Reader fr = new FileReader("fileinputstream\\data.txt");

方法名称说明
public int read()次读取一个字符返回,如果字符已经没有可读的返回-1
// 读取一个字符返回,没有可读的字符了返回-1
int code = fr.read();
System.out.print((char)code);

int code1 = fr.read();
System.out.print((char)code1);

// 使用循环读取字符
int code;
while ((code = fr.read()) != -1){
    System.out.print((char) code);
}

存在问题:性能较慢


方法名称说明
public int read(char[] buffer)每次读取一个字符数组,返回读取的字符个数,如果字符已经没有可读的返回-1
char[] buffer = new char[1024]; // 1K字符
int len;
while ((len = fr.read(buffer)) != -1) {
    String rs = new String(buffer, 0, len);
    System.out.print(rs);
}

读取的性能得到了提升
解决读取中文字符输出乱码问题

5 FileWriter:文件字符输出流

  • 作用:以内存为基准,把内存中的数据以字符的形式写出到磁盘文件中去的流
构造器说明
public FileWriter(File file)创建字符输入流管道与源文件对象接通
public FileWriter​(File file,boolean append)创建字符输出流管道与源文件对象接通,可追加数据
public FileWriter(String pathname)创建字符输入流管道与源文件路径接通
public FileWriter​(String filepath,boolean append)创建字符输出流管道与源文件路径接通,可追加数据
方法名称说明
void write(int a)写一个字符出去
void write(char[] cbuf)写一个字符数组出去
void write(char[] cbuf , int pos , int len)写一个字符数组的一部分出去
void write​(String str)写一个字符串
void write​(String str, int off, int len)写一个字符串的一部分
flush()刷新流,还可以继续写数据
close()关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据
// a.public void write(int c):写一个字符出去
fw.write(98);
fw.write('a');
fw.write('徐'); // 不会出问题了
fw.write("\r\n"); // 换行

// b.public void write(String c)写一个字符串出去
fw.write("方佬肆fang");
fw.write("\r\n"); // 换行

// c.public void write(char[] buffer):写一个字符数组出去
char[] chars = "方佬肆fang".toCharArray();
fw.write(chars);
fw.write("\r\n"); // 换行

// d.public void write(String c ,int pos ,int len):写字符串的一部分出去
fw.write("方佬肆fang", 0, 5);
fw.write("\r\n"); // 换行

// e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
fw.write(chars, 3, 5);
fw.write("\r\n"); // 换行

fw.flush();// 刷新后流可以继续使用
fw.close(); // 关闭包含刷线,关闭后流不能使用

6 IO流资源释放方式

try-catch-finally

  • finally:放在try-catch后面的,无论是正常执行还是异常执行代码,最后一定要执行,除非JVM退出。
  • 作用:一般用于进行最后的资源释放操作(专业级做法)
try {
	FileOutputStream fos = new FileOutputStream("a.txt");
	fos.write(97); 
	} catch (IOException e) {
		e.printStackTrace();
	}finally {
        //无论代码是正常结束,还是出现异常都要最后执行这里
        try {
        // 关闭流。
        if(os!=null)os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if(is != null) is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

try-with-resource

  • 自动释放资源、代码简洁
// 定义输入流对象;
// 定义输出流对象;
// try(输入流对象;输出流对象){
// 		可能出现异常的代码;
// 	}catch(异常类名 变量名){
// 		异常的处理代码;
// 	}
// 资源用完最终自动释放
try (
// 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
      // 1、创建一个字节输入流管道与原视频接通
     InputStream is = new FileInputStream("file-io-app/src/out04.txt");
      // 2、创建一个字节输出流管道与目标文件接通
     OutputStream os = new FileOutputStream("file-io-app/src/out05.txt");
      ) {
  // 3、定义一个字节数组转移数据
  byte[] buffer = new byte[1024];
  int len; // 记录每次读取的字节数。
  while ((len = is.read(buffer)) != -1){
      os.write(buffer, 0 , len);
  }
  System.out.println("复制完成了!");
} catch (Exception e){
  e.printStackTrace();
}
// 资源用完最终自动释放
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值