JAVA学习小计之IO流01-字节流篇

IO流的分类

  1. 文件流分为字节流字符流
  • 字节流以字节为传输单位,适用于二进制文件(图片、视频等);
  • 字符流以字符为传输单位,根据不同的编码方式字符单位的大小也不同,适用于文件传输;
  1. 根据数据的流向分为:输入流 和 输出流

  • 输入流 :把数据从其他设备上读取到内存中的流。
  • 输出流 :把数据从内存 中写出到其他设备上的流。

输入也叫做读取数据,输出也叫做作写出数据

上面这四个类衍生出一系列类,它们是最根本的,但它们都是抽象类,需要其子类来实现其方法。

PS:我们必须明确一点的是,一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据


字节流

字节输入流(InputStream):

java.io.InputStream抽象类是表示字节输入流的所有类的父类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。


文件输入流FileInputStream:

  • FileInputStream是继承了InputStream的类,也就表明其是以字节为传输单位
  • 其作用是从文件读取数据,输出到控制台
FileInputStream的构造方法

1、 FileInputStream(File file) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
2、 FileInputStream(String name)通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名name命名。

同样的,推荐使用第二种构造方法

FileInputStream inputStream = new FileInputStream("D:\code\JavaDemo\a.txt");

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FileNotFoundException 。

构造举例,代码如下:

public class FileInputStreamConstructor throws IOException{
    public static void main(String[] args) {
   	 	// 方法1:使用File对象创建流对象
        File file = new File("a.txt");
        FileInputStream fos = new FileInputStream(file);
      
        // 方法2:使用文件名称创建流对象(推荐使用)
        FileInputStream fos = new FileInputStream("b.txt");
    }
}

案例代码(利用字节数组形式): 

新建文本,名字为a,路径为D:\\code\\JavaDemo\\a.txt,内容为abcde。

package com.logindemo.IO;

import java.io.FileInputStream;
import java.io.IOException;

public class f1 {
    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        int readData=0;
        byte[] rData = new byte[2];
        int len = 0;   //记录每一轮实际读取的字节数
        try {
            //创建字节文件流对象
            fileInputStream = new FileInputStream("D:\\code\\JavaDemo\\a.txt");
            //循环读取
            while ((len = fileInputStream.read(rData)) != -1) {
                //设置字节数组,一次最多可读取2字节
                //读取结束后,把数组变成字符串打印出来,从下标0开始
                System.out.print(new String(rData, 0, len));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //读取完毕要关闭文件输入流
            try {
                fileInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

运行结果:确实是abcde~~~读取数据成功~

代码解析几点:

(1)读取字节:read()每次读取一个字节,返回该字节对应的int值,读取到文件末尾返回-1;

后面需要转成字符型打印出来。但是这种方式不太好处理中文,一个汉字可能会对应多个字节,所有更推荐数组↓

(2)使用字节数组读取public int read(byte[] b)每次读取b的长度个字节到数组中,返回该字节数组的有效数组长度,并将读取到的有效字节存储到字节数组中,后面需要把数组变成字符串打印出来。读取到末尾时,返回-1


  1. String构造器有一个是将字符数组转化为字符串,参数为(数组,起点,长度)
  2. 要设置finally以关闭IO流

补充:为什么需要len?

我们先看没有len的情况,只图中改这一行代码:

 

运行可以发现,输出的是abcded!多了一个d!显然不对!!为什么会出现这种情况?看图分析!

 所以得出结论:要通过len ,获取有效的字节!!!


文件输出流FileOutputStream:

  • FileOutputStream是OutputStream的子类,表明其是按字节进行输出
  • 其作用是向文件写入数据

FileOutputStream的构造方法:

1、 public FileOutputStream(File file):根据File对象为参数创建对象。
2、 public FileOutputStream(String name): 根据名称字符串为参数创建对象。

推荐第二种构造方法 :

FileOutputStream outputStream = new FileOutputStream("D:\code\JavaDemo\a.txt");

同样的,当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FileNotFoundException 。

在该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。

构造举例,代码如下:

public class FileOutputStreamConstructor throws IOException {
    public static void main(String[] args) {
   	 	// 使用File对象创建流对象
        File file = new File("D:\code\JavaDemo\a.txt");
        FileOutputStream fos = new FileOutputStream(file);
      
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("D:\code\JavaDemo\b.txt");
    }
}

案例代码:

新建文本,名字为b,路径为D:\\code\\JavaDemo\\a.txt,内容为abc。

package com.logindemo.IO;

import java.io.FileOutputStream;
import java.io.IOException;

public class f2 {
    public static void main(String[] args) {
        FileOutputStream fileOutputStream = null;
        String path = "D:\\code\\JavaDemo\\b.txt";
        try {
            //fileOutputStream=new FileOutputStream(path);  //这个会清空原有内容,即覆盖
            //设置追加而不是覆盖的写法
            fileOutputStream = new FileOutputStream(path, true);  //不会清空,即追加
            //写入单个字符
            //fileOutputStream.write('a');
            //设置一次添加多个字符
            String s1 = "hello";
            fileOutputStream.write(s1.getBytes());  //字符串转换为字节数组
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //关闭输出流
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

运行结果:

代码解析几点:

(1)写出字节write(int b) 方法,每次可以写出一个字节数据;

(2)写出字节数组write(byte[] b),每次可以写出数组中的数据;


追加新数据:true 表示追加数据,false 表示不追加也就是清空原有数据;

write方法中接收的是char型字符或者是数组;

s1.getBytes():把字符串“hello”转换为字节数组;

补充知识:

写出指定长度字节数组write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节 

改一下原代码框的位置,加off和len的值,我们要追加从索引2开始的2个字节,hello,即ll,可以发现确实是追加了ll:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值