File、IO流(二)

本文详细介绍了JavaIO流的概念,包括按流方向和数据单位的分类,重点讲解了字节输入流、字符输入流、字节输出流和字符输出流的区别与用途,并给出了FileInputStream和FileOutputStream的实例以及文件复制的应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO流

  • 输入输出流,读写数据的
  • I指Input,称为输入流:负责把数据读取到内存中去
  • O指Output,称为输出流:负责写数据出去

IO流的分类

按流的方向分为:

按流中数据单最小的单位,分为:

IO流的体系

 字节输入流                字节输出流                字符输入流                字符输出流

 总结流的四大类

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

FileInputStream(文件字节输入流)

  • 作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去。
构造器说明
public FileInputStream(File file)创建字节输入流管道于源文件连通
public FileInputStream(String pathname)创建字节输入流管道于源文件连通
方法名称说明
public int read()每次读取一个字符返回,如果发现没有数据可读会返回-1
public int read(byte[ ] buffer)

每次用一个字符数组去读取数据,返回字符数组读取了多少个字符

如果发现没有数据可读会返回-1

读取单个字节 

文本文件中的内容为:ab 

import java.io.FileInputStream;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws Exception {
        // 创建文件字节输入流管道,与源文件连通
        InputStream is = new FileInputStream(("IdeaProjects\\test\\src\\com\\test\\test"));

        // 开始读取文件的字节数据
        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(b3);
    }
}

 当文本的内容较多时用上述方法就会非常麻烦,所以我们可以通过循环改造上述代码

import java.io.FileInputStream;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws Exception {
        // 创建文件字节输入流管道,与源文件连通
        InputStream is = new FileInputStream(("IdeaProjects\\test\\src\\com\\test\\test"));

        // 使用循环改造代码
        int b; // 用于记住读取的字节
        while ((b = is.read()) != -1){
            System.out.print((char)b);
        }
    }
}

注意事项:

  • 使用FileInputStream每次读取一个字节,读取性能较差,并且读取汉字输出会乱码。

读取多个字节 
import java.io.FileInputStream;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws Exception {
        // 创建一个字节输入流对象代表字节输入流管道,与源文件连通
        InputStream is = new FileInputStream(("IdeaProjects\\test\\src\\com\\test\\test"));

        // 文本内容为:abc66
        // 开始读取文件中的字节数据,每次读取多个字符
        // public int read(byte b[]) throws IOException
        // 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1
        byte[] buffer = new byte[3];
        int len = is.read(buffer);
        String rs = new String(buffer);
        System.out.println(rs);
        System.out.println("当前读取的字节数量:" + len);

        // buffer = [abc]
        // buffer = [66c]
        int len2 = is.read(buffer);
        // 注意:读取多少,倒出多少
        String rs2 = new String(buffer,0,len2);
        System.out.println(rs2);
        System.out.println("当前读取的字节数量:" + len2);

        int len3 = is.read(buffer);
        System.out.println(len3); // -1
    }
}

用循环改造上述代码:

import java.io.FileInputStream;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws Exception {
        // 创建一个字节输入流对象代表字节输入流管道,与源文件连通
        InputStream is = new FileInputStream(("IdeaProjects\\test\\src\\com\\test\\test"));

        // 文本内容为:abc66
        // 开始读取文件中的字节数据,每次读取多个字符
        // public int read(byte b[]) throws IOException
        // 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1
        byte[] buffer = new byte[3];
        int len = is.read(buffer);
        while ((len = is.read(buffer)) != -1){
            // 注意:读取多少,倒出多少
            String rs = new String(buffer,0,len);
            System.out.print(rs);
        }
        is.close(); //关闭流
    }
}

注意事项:

  • 使用FileInputStream每次读取多个字节,读取性能得到了提升,但读取汉字输出还是会乱码。

一次性读取完全部字节 
  • 方式一:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次性读完文件的全部字节。
方法名称说明
public int read(byte [ ] buffer)

每次用一个字节数组去读取,返回字节数组读取了多少字节,

如果没有发现数据可读会返回-1

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws Exception {
        // 创建一个字节输入流对管道与源文件连通
        InputStream is = new FileInputStream(("IdeaProjects\\test\\src\\com\\test\\test"));

        // 准备一个字节数组,大小与文件的大小正好一样
        File f = new File("IdeaProjects\\test\\src\\com\\test\\test");
        long size = f.length();
        byte[] buffer = new byte[(int) size];

        int len = is.read(buffer);
        System.out.println(new String(buffer));

        System.out.println(size);
        System.out.println(len);
    }
}
  • 方式二:Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。

直接把文件数据全部读取到一个字节数组可以避免乱码,但仍可能出现的问题: 

  • 如果文件过大,创建的字节数组也会过大,可能引起内存溢出
  • 读文本内容更适合用字符流
  • 字节流适合做数据的转移,如:文件复制等

FileOutputStream(文件字节输出流)

  • 作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。
import java.io.FileOutputStream;
import java.io.OutputStream;

public class Test {
    public static void main(String[] args) throws Exception {
        // 覆盖管理:覆盖之前的数据
        //OutputStream os = new FileOutputStream("IdeaProjects\\test\\src\\com\\test\\test");

        // 追加管数据道
        OutputStream os = new FileOutputStream("IdeaProjects\\test\\src\\com\\test\\test",true);

        // 开始写数据出去
        os.write(97); // 97就是一个追加,代表a
        os.write('b'); // ‘b’也是一个字节
        // os.write('人') // 汉字在UTF-8下占三个字节,默认只能写出去一个字节

        byte[] bytes = "我爱你中国abc".getBytes();
        os.write(bytes);

        os.write(bytes,0,15);

        //换行符
        os.write("\r\n".getBytes());
        os.close(); //关闭流
    }
}

案例:文件复制

需求:将一张图片从D盘复制到C盘

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Test {
    public static void main(String[] args) throws Exception {
        // 创建一个字节输入流管道与源文件连通
        InputStream is = new FileInputStream("D:/tp/123/666.jpg");
        // 创建一个字节输出流管道与源文件连通
        OutputStream os = new FileOutputStream("C:/abc/qwer/666.jpg");

        // 创建一个字节数组,负责转移字节数据
        byte[] bytes = new byte[1024];
        // 从字节输入流中读取字节数据,写出去到字节输出流中,读多少写出去多少
        int len; // 记住每次读取了多少字节
        while ((len = is.read()) != -1){
            os.write(bytes,0,len);
        }
        os.close();
        is.close();
        System.out.println("复制完成");
    }
}

字节流非常适合做一切文件的复制操作

        任何文件的底层都是字节,字节流做复制,是一字不漏的转移完全部字节,只要复制后的文件格式一致就没有问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值