Java:字节输入流、字节输出流

Java:缓冲流
Java:字节输入流、字节输出流
Java:字符输入流、字符输出流
Java: IO流资源的释放方式
Java:输入输出转换流

在这里插入图片描述

字节输入流 FileInputStream

以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。

构造器说明
public FileInputStream​(File file)创建字节输入流管道与源文件对象接通
public FileInputStream​(String pathname)创建字节输入流管道与源文件路径接通
方法说明
public int read()每次读取一个字节返回,如果字节已经没有可读的返回-1
public int read(byte[] buffer)每次读取一个字节数组返回,如果字节已经没有可读的返回-1

单字节读入

注意:
在UTF-8编码中,一个中文占3个字节,此时用read方法读入,将会出现乱码问题。

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

public class FileInputStreamDemo01 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个文件字节输入流管道与源文件接通。
        // InputStream is = new FileInputStream(new File("file-io-app\\src\\data.txt"));
        // 简化写法
        InputStream is = new FileInputStream("file-io-app\\src\\data.txt");

        // 2、读取一个字节返回 
//        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);

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

按字节数组读入

需要注意的是

当文本中有中文字符时,按字节数组读入仍可能存在乱码问题。

若直接把一个文件读取到字节数组中,可能会因为文件过大,造成内存溢出。

在可预见文件大小不会引起内存溢出的情况下,可以定义和文件相同大小的字节数组。这样就能一次读完。

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

public class FileInputStreamDemo02 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个文件字节输入流管道与源文件接通
        InputStream is = new FileInputStream("file-io-app/src/data02.txt");

        // 2、定义一个字节数组,用于读取字节数组
//        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

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

一次读完整个文件

方式一
自己定义一个字节数组与文件的大小一样大,然后使用读取字节数组的方法,一次性读取完成,但要注意是否会引起内存溢出。

方式二
官方为字节输入流InputStream提供了如下API可以直接把文件的全部数据读取到一个字节数组中。
在这里插入图片描述

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

/**
   目标:使用文件字节输入流一次读完文件的全部字节。可以解决乱码问题。
 */
public class FileInputStreamDemo03 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个文件字节输入流管道与源文件接通
        File f = new File("file-io-app/src/data03.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));

    }
}

字节输出流 FileOutputStream

以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去的流。

构造器

在这里插入图片描述
append的值为true时,为追加数据;反之则为重写,新的输出将覆盖原文件内容。默认为false

输出方法

在这里插入图片描述

输出换行时使用\r\n更好。

os.write(“\r\n”.getBytes()); 

流刷新与关闭

在这里插入图片描述

代码示例

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class OutputStreamDemo04 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个文件字节输出流管道与目标文件接通
        OutputStream os = new FileOutputStream("file-io-app/src/out04.txt" , true); // 追加数据管道
//        OutputStream os = new FileOutputStream("file-io-app/src/out04.txt"); // 先清空之前的数据,写新数据进入

        // 2、写数据出去
        // a.public void write(int a):写一个字节出去
        os.write('a');
        os.write(98);
        os.write("\r\n".getBytes()); // 换行
        // os.write('徐'); // [ooo]

        // b.public void write(byte[] buffer):写一个字节数组出去。
        byte[] buffer = {'a' , 97, 98, 99};
        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(); // 释放资源,包含了刷新的!关闭后流不可以使用了
    }
}

文件拷贝示例

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

/**
 *   目标:学会使用字节流完成文件的复制(支持一切文件类型的复制)
 */
public class CopyDemo05 {
    public static void main(String[] args) {
        try {
            // 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("复制完成了!");

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

Java: IO流资源的释放方式

Java:字节输入流、字节输出流
Java:字符输入流、字符输出流

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值