FileInputStream,FileOutputStream 和 FileReader ,FileWriter 类的基本使用【 File类+IO流知识回顾②】

IO 流

IO流.jpg

IO流的概念

• I/O 即输入Input/ 输出Output的缩写,其实就是计算机调度把各个存储中(包括内存和外部存储)的数据写入写出的过程;
• java中用“流(stream)”来抽象表示这么一个写入写出的功能,封装成一个“类”,都放在http://java.io这个包里面。

什么是流?

一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。

IO流的分类

  1. 从流的方向分类(相较于内存的方向)
    1. 输入流:只能从中读取数据。把数据从其他设备读取到内存中的流
    2. 输出流:只能向其写入数据。把数据从内存中写到其他设备上的流

yuque_diagram.jpg

  1. 从流的数据类型分类
    1. 字节流:以字节为单位,读写数据的流,可以操作任何数据(主要由InputStream和outPutStream作为基类
    2. 字符流:以字符为单位,读写数据的流,只能操作纯字符数据,比较方便(主要由Reader和Writer作为基类
  2. 按照流的角色划分
    1. 节点流(低级流):可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流
    2. 处理流(高级流):用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能。
  1. Java语言中的所有字节流都以Stream结尾。所有的字符流都含有Reader或Writer。
  2. 字节流适合读取:视频,声音,图片等二进制文件
  3. 字符流适合读取:纯文本文件。
  4. Java中一个字符占两个字节,即字符流一次读取两个字节,字节流一次读取一个字节。

字节流

字节输出流

image.png

OutPutStream

OutPutStream 是一个抽象类,并且是所有字节输出流类的父类,它定义了一些字节输出流的基本共性功能方法。

方法名称功能描述
public abstract void write(int b)将指定的字节输出流
public void write(byte b[])将b.length个字节从指定的字节数组写入此输出流
public void write(byte b[], int off, int len)从指定的字节数组写入len字节,从偏移量off开始输出到此输出流。
public void flush()刷新此输出流并强制任何缓冲的输出字节被写出。
public void close()关闭并释放与当前输出流相关联的任何系统资源
FileOutputStream

构造方法
image.png

FileOutputStream(String name)
FileOutputStream(String name,boolean append)
FileOutputStream(File file)
FileOutputStream(File file,boolean append)
FileOutputStream(FileDescriptor fdObj)

文件输出流,将数据写出到文件。

  1. write(int b)
// 1.创建FileOutputStream对象
String fptFilePath = "D:\\fpt.txt";
FileOutputStream fpt = new FileOutputStream(fptFilePath);
// 2. 写入数据
fpt.write(65);
fpt.write(66);
fpt.write(67);
// 3.关闭释放流
fpt.close();

image.png

  1. write(byte b[])
String fptFilePath = "D:\\fpt.txt";
FileOutputStream fpt = new FileOutputStream(fptFilePath);
byte[] bytes = "中文输出".getBytes(Charset.defaultCharset());
fpt.write(bytes);
fpt.close();
  1. write(byte b[],int offset,int len)
String fptFilePath = "D:\\fpt.txt";
FileOutputStream fpt = new FileOutputStream(fptFilePath);
byte[] bytes = "abcdefg".getBytes();
fpt.write(bytes,1,3);
fpt.close();

image.png
追加模式,使用 FileOutputStream(String name,boolean append) 或 FileOutputStream(File file,boolean append) 创建文件输出流对象即可。

String fptFilePath = "D:\\fpt.txt";
FileOutputStream fpt = new FileOutputStream(fptFilePath,true);
fpt.write("追加内容".getBytes());
fpt.close();

字节输入流

在这里插入图片描述

InputStream

InputStream 是一个抽象类,并且是字节输入流类的父类,可以读取字节信息到内存中,它定义了字节输入流的基本共性功能方法。

方法名称功能描述
public abstract int read()从输入流中读取数据的下一个字节
public int read()从输入流中读取一个字节返回int型变量,若到达文件末尾,则返回-1
public int read(byte b[])从输入流中读取b.length个字节到字节数组中,返回读入缓冲区的总数,若到达文件末尾,则返回-1
public int read(byte b[], int off, int len)从输入流中读取最多len个字节到字节数组中(从数组的off位置开始存储字节),当len为0时则返回0,如果len不为0,则该方法将阻塞,直到某些输入可用为止。
public void close()关闭并释放与此输入流关联的系统资源
FileInputStream

FileInputStream 类是文件输入流,从文件中读取字节。

构造方法:image.png

  1. read() 单个字节读取
String filePath = "D:\\fis.txt";
FileInputStream fis = new FileInputStream(filePath);
int readOne = fis.read();
System.out.println(readOne);
System.out.println((char)readOne);
fis.close();
  1. read(byte b[]) 字节数组读取
String filePath = "D:\\fis.txt";
FileInputStream fis = new FileInputStream(filePath);

// 1. 定义len
int len;
byte b = new byte[10]; // 字节数组长度为10,每次读取10个字节
// 2.循环读取
while((len=fis.read(b))!=-1){
	// 每次读取后,把数组的有效字节部分,变成字符串打印
    System.out.println(new String(b,0,len)); //读取有效值,防止重复读取
}
fis.close();
  1. read(byte b[],int off,int len) 字节数组读取(指定读取起始点)
String filePath = "D:\\fis.txt";
FileInputStream fis = new FileInputStream(filePath);
byte[] b = new byte[10];
int len;
while ((len = fis.read(b,0,10))!=-1){
    System.out.println(new String(b,0,len));
}

文件拷贝,图片音视频复制

public static void copyVideoImage(String targetFilePath,String optFilePath) throws IOException {

    // 1.创建FileInputStream对象和FileOutputStream对象
    FileInputStream fis = new FileInputStream(targetFilePath);
    FileOutputStream fos = new FileOutputStream(optFilePath);

    // 2.读取设置
    int len; // 长度
    byte b[] = new byte[1024]; // 每次读取1024字节

    // 3.循环读取和写入
    while ((len=fis.read(b))!=-1){ // 每次读取1024个字节到数组中,并且返回此次读入的长度
        fos.write(b,0,len); // 写出从索引0开始的len个字节
    }

    // 4.关闭输入流和输出流
    fis.close();
    fos.close();
    // 5.
    System.out.println("copy完毕");
}


public static void main(String[] args) throws IOException {
    // 文件源目录
    String filePath = "C:\\Users\\robin\\Desktop\\项目资源文件\\音视频文件\\steamin使用教程.mp4";
    //文件拷贝目录
    String optFilePath = "C:\\Users\\robin\\Desktop\\项目资源文件\\音视频文件\\steamin拷贝.mp4";
    copyVideoImage(filePath,optFilePath);
}

字符流

字符流本质就是基于字节流读取时,去查了指定的码表,而字节流之间读取数据会有乱码问题(常见的中文乱码)。

FileInputStream 读取文本文件,会出现中文乱码

public static void main(String[] args) throws IOException {
    String filePath = "D:\\1.txt";
    FileInputStream fis = new FileInputStream(filePath);
    int len;
    byte b[] = new byte[4];
    while((len=fis.read(b))!=-1){
        System.out.println(new String(b));
    }
}

image.png

字符输入流

Reader

Reader是一个抽象类,是字符输入流类的父类,可以读取字符信息到内存中,它定义了字符输入流的基本共性功能方法。
在这里插入图片描述

public void close()关闭此流并释放资源
public void read()从输入流读取一个字符
public int read(char[] cbuf)从输入流中读取一些字符,并将它们存储到字符数组 cbuf 中
FileReader

FileRead类是读取字符文件的一个类。构造时使用系统默认的字符编码和默认字节缓冲区。

String filePath = "D:\\1.txt";
FileReader fileReader = new FileReader(filePath);
int len ; // 用来记录每次读取的字符,并且用于判断文件是否读到了文件末尾
while ((len= fileReader.read())!=-1){
    System.out.println((char)len);
}
fileReader.close()

字符输出流

Writer

Writer是一个抽象类,并且是所有字符输出流类的父类,将指定的字符信息写到目的文件中。同样的,定义了字符输出流的基本共性功能方法。

void write(int c)写入单个字符
void write(char[] cbuf)写入字符数组
abstract void write(char[] cbuf,int off,int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数
void write(String str)写入字符串
void write(String str,int off,int len)写入字符串的某一部分,off表示字符串的开始索引,len表示写的字符个数
void flush()刷新该流的缓冲
void close()先刷新,再关闭此流
FileWriter

在这里插入图片描述

write(int b),每次写出一个字符数据

// 字符输出流
String filePath = "D:\\writer.txt";
FileWriter fw =null;
try{
   fw = new FileWriter(filePath);
   fw.write('c');
   fw.write("知更鸟");
   fw.write("robin");
}catch (IOException e){
    System.out.println(e.getMessage());
}finally {
    try {
        if(fw!=null){
            fw.close();
        }
    }catch (IOException e){
        System.out.println(e.getMessage());
    }
}

image.png

注意,使用FileWriter时,一定要记得流的关闭或者是刷新,因为如果不关闭的话,数据只是保存到缓冲区,而不是文件,这一点与FileOutputStream不同。

关闭close和刷新flush

因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush 方法了。
flush :刷新缓冲区,流对象可以继续使用。
close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了

文本文件复制
public static void main(String[] args) {
    // 文件源目录和目的目录
    String filePath = "D:\\reader.txt";
    String optFilePath = "D:\\writer.txt";
    copyTxt(filePath,optFilePath);
}


public static void  copyTxt(String sourceFilePath,String targetFilePath){
    // 1.创建FileReader对象和FileWriter对象
    FileReader reader = null;
    FileWriter writer = null;
    // 2.规范一点try catch
    try {
        reader = new FileReader(sourceFilePath);
        writer = new FileWriter(targetFilePath);
        // 3. 开始循环读取写入数据
        char cbuf[] = new char[1024];
        int len;
        while ((len = reader.read(cbuf))!=-1){
            writer.write(cbuf,0,len); // 将cbuf写入到wirter中,每次从cbuf数组的0索引开始写入,并且写入Len个字符(len刚好是每次读取的字符数)
        }
    }catch (IOException e){
        System.out.println(e.getMessage());
    }finally {
        try {
            // 4.判断字符流对象是否为空,然后释放资源
            if(reader!=null){
                reader.close();
            }
            if(writer!=null){
                writer.close();
            }
        }catch (IOException e){
            System.out.println(e.getMessage());
        }
    }
}

小结

  1. Java语言中的所有字节流都以Stream结尾所有的字符流都含有Reader或Writer
  2. 字节流适合读取:视频,声音,图片等二进制文件
  3. 字符流适合读取:纯文本文件。
  4. Java中一个字符占两个字节,即字符流一次读取两个字节,字节流一次读取一个字节。
  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是使用字节流和字符流分别复制文件的示例代码: 使用字节流复制文件: ```java import java.io.*; public class ByteStreamCopy { public static void main(String[] args) { String srcFile = "source.txt"; String destFile = "destination.txt"; try (FileInputStream fis = new FileInputStream(srcFile); FileOutputStream fos = new FileOutputStream(destFile)) { byte[] buffer = new byte[1024]; int length; while ((length = fis.read(buffer)) > 0) { fos.write(buffer, 0, length); } System.out.println("File copied successfully using byte stream."); } catch (IOException e) { e.printStackTrace(); } } } ``` 使用字符流复制文件: ```java import java.io.*; public class CharacterStreamCopy { public static void main(String[] args) { String srcFile = "source.txt"; String destFile = "destination.txt"; try (FileReader reader = new FileReader(srcFile); FileWriter writer = new FileWriter(destFile)) { char[] buffer = new char[1024]; int length; while ((length = reader.read(buffer)) > 0) { writer.write(buffer, 0, length); } System.out.println("File copied successfully using character stream."); } catch (IOException e) { e.printStackTrace(); } } } ``` 以上两个示例代码中,都使用了try-with-resources语句来自动关闭文件流。在使用字节流复制文件时,定义了一个长度为1024的字节数组作为缓冲区,每次读取文件时将数据读入缓冲区,然后再将缓冲区中的数据写入目标文件。在使用字符流复制文件时,也定义了一个长度为1024的字符数组作为缓冲区,使用reader.read(buffer)方法读取文件数据,然后使用writer.write(buffer)方法将数据写入目标文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杀死一只知更鸟debug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值