3.IO字节流

1. IO流概述和分类

  1. IO流概述
  • IO:输入/输出(Input/Output)
  • 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流本质是数据传输
  • IO流就是用来处理设备间数据传输问题的
    • 常见的应用:文件复制;文件上传;文件下载等
  1. IO流的分类
  • 按照数据的流向

    • 输入流:读数据
    • 输出流:写数据
  • 按照数据类型来分

    • 字节流
      • 字节输入流;字节输出流
    • 字符流
      • 字符输入流;字符输出流

一般情况下,IO流的分类是按照数据类型来分的

  • 字节流和字符流在什么情况下使用
    • 吐过数据通过Window自带的记事本软件打开,我们还可以读懂里面的内容,就是用字符流;否则使用字节流。如果不知道用那种类型的流,就是用字节流。

2.字节流写数据

  1. 字节流抽象基类
  • InputeStream:这个抽象类是表示字节输入流的所有类的超类。

  • OutputStream:这个抽象类是表示字节输出流的所有类的超类。

  • 子类名特点:子类名称都是以其父类名作为子类名的后缀

  1. 字节流写数据
  • FileOutputStream:文件输出流用于将数据写入File

  • FileOutputStream(String name):创建文件输出流以指定的名称写入文件

  1. 使用字节输出写数据的步骤
    • 创建字节流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
    • 调用字节输出流对象的写数据方法
    • 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
package study01;

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

/*
- `FileOutputStream:`文件输出流用于将数据写入File
- `FileOutputStream(String name):`创建文件输出流以指定的名称写入文件
*/
public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("Stuay01\\fos.txt");
        /*- 做了三件事:
	- ①:调用系统功能创建了文件
	- ②:创建了字节输出流对象
	- ③:让字节输出流对象指向创建好的文件*/

    //void write(int b):将指定的字节写入此文件输出流
        fileOutputStream.write(89);
        fileOutputStream.write(55);
        fileOutputStream.write(57);

//        所有和IO相关的操作最后都要释放资源
//        void close():关闭此文件输出流并释放与此流相关联的任何系统资源
        fileOutputStream.close();
    }
}

3. 字节流写数据的3中方式

  1. 构造方法

    • FileOutputStream(String name):创建文件输出流以指定的名称写入文件------一般用它
    • FileOutStream(File file):创建文件输出流以写入指定的File对象表示的文件
方法名说明
void write(int b)将指定的字节写入此文件输出流,一次写一个字节数据
void write(byte[] b)b.length长度的字节从指定的字节数组写入此文件输出流,一次写一个字节数组数据
void write(byte[] b,int off,int len)将长度为len的字节从指定的字节数组开始,从偏移量off开始写入此文件输出流,一次写一个字节数组的部分数据。
  • 案例
package study01;

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

/*1. 构造方法(两种方式效果相同)
	- `FileOutputStream(String name):`创建文件输出流以指定的名称写入文件------一般用它
	- `FileOutStream(File file)`:创建文件输出流以写入指定的File对象表示的文件

| 方法名                                  | 说明
| `void write(int b)`                    | 将指定的字节写入此文件输出流,一次写一个字节数据
| `void write(byte[] b)`                 | 将`b.length`长度的字节从指定的字节数组写入此文件输出流,一次写一个字节数组数据
| `void write(byte[] b,int off,int len)` | 将长度为`len`的字节从指定的字节数组开始,从偏移量`off`开始写入此文件输出流,一次写一个字节数组的部分数据。
 */
public class FileOutputStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //创建字节流输出对象
        FileOutputStream fox = new FileOutputStream("Stuay01\\fos1.txt");
/*//        | `void write(int b)`                    | 将指定的字节写入此文件输出流,一次写一个字节数据
        fox.write(97);
        fox.write(98);
        fox.write(99);
        fox.write(100);*/

/*//        | `void write(byte[] b)`                 | 将`b.length`长度的字节从指定的字节数组写入此文件输出流,一次写一个字节数组数据
//        byte[] bytes = {97,98,99,100};
        //byte[] getBytes():返回字符串对应的字节数组
        byte[] bytes = "abcde".getBytes();
        fox.write(bytes);*/
//        | `void write(byte[] b,int off,int len)` | 将长度为`len`的字节从指定的字节数组开始,从偏移量`off`开始写入此文件输出流,一次写一个字节数组的部分数据。
        byte[] bytes = "abcde".getBytes();
//        fox.write(bytes,0,bytes.length);
        fox.write(bytes,1,3);
//        释放资源
        fox.close();
    }
}

4. 字节流写数据的两个小问题

  1. 字节流写数据如何实现换行

    不同操作系统对换行符的识别是不同的

    • windows:\r\n
    • linux:\n
    • mac:\r
  2. 字节流写数据如何实现追加写入

public FileOutputStream(File file,
                        boolean append)
                 throws FileNotFoundException

创建文件输出流以写入由指定的File对象表示的文件。 如果第二个参数为true ,则字节将写入文件的末尾而不是开头

package study01;
/*1. 字节流写数据如何实现换行
	不同操作系统对换行符的识别是不同的
	- `windows:\r\n`
	- `linux:\n`
	- `mac:\r`

2. 字节流写数据如何实现追加写入

public FileOutputStream(File file, boolean append) throws FileNotFoundException
创建文件输出流以写入由指定的`File`对象表示的文件。  如果第二个参数为`true` ,则字节将写入文件的末尾而不是开头*/

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

public class FileOutputStreamDemo02 {
    public static void main(String[] args) throws IOException {
        //创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("Stuay01\\fos2.txt",true);
        //写数据
        for (int i = 0;i<10;i++){
            fos.write("hello".getBytes());
            fos.write("\r\n".getBytes());
        }
        //释放资源
        fos.close();
    }
}

5. 字节流写数据加异常处理

finally:在异常处理时提供finally块来执行所有清除操作。比如说IO流中的释放资源。

特点:被finally控制的语句一定会执行,除非JVM退出

try{
  可能出现异常的代码;
}catch(异常名 变量名){
  异常处理的代码;
}finally{
  执行所有清除操作;
}
  • 代码示例
package study01;

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

public class FileOutputStreamDemo03 {
    public static void main(String[] args) {
//        try {
//            FileOutputStream fos = new FileOutputStream("Stuay01\\fos2.txt");
//            fos.write("hello".getBytes());
//            fos.close();
//        } catch (IOException e){
//            e.printStackTrace();
//        }

        //加入finally来实现释放资源
        FileOutputStream fos = null;
        try {
             fos = new FileOutputStream("Stuay01\\fos2.txt");
            fos.write("hello".getBytes());

        } catch (IOException e){
            e.printStackTrace();
        }finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

6.字节流读数据(一次读一个字节数据)

  1. 需求:把文件fos.txt中的内容读取出来在控制台输出

  2. FileInputStream:从文件系统中的文件获取输入字节

    • FileInputStream(String name):通过打开与实际文件的链接来创建一个FileInputStream,该文件由文件系统中的路径名name命名
  3. 使用字节输入流读数据的步骤:

    • 创建字节输入流对象
    • 调用字节输入流对象的读数据方法
    • 释放资源
  4. 读数据的方法

方法说明
int read()从该输入流读取一个字节的数据。 当文件中没有数据了读取的返回值为-1
int read(byte[] b)从该输入流读取最多 b.length个字节的数据到一个字节数组。
int read(byte[] b, int off, int len)从该输入流读取最多 len个字节的数据到字节数组。
package Study02;

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

/*
1. 需求:把文件`fos.txt`中的内容读取出来在控制台输出

2. `FileInputStream`:从文件系统中的文件获取输入字节
	- `FileInputStream(String name)`:通过打开与实际文件的链接来创建一个`FileInputStream`,该文件由文件系统中的路径名`name`命名
3. 使用字节输入流读数据的步骤:
	- 创建字节输入流对象
	- 调用字节输入流对象的读数据方法
	- 释放资源
	*/
public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        //FileInputStream(String name)
        FileInputStream fis = new FileInputStream("Stuay01\\fos2.txt");//fos2.txt中的内容为:hello

        //调用字节输入流对象的读数据方法
        //`int read()`从该输入流读取一个字节的数据。 当文件中没有数据了读取的返回值为-1
        /*// 第一次读取数据
        int read = fis.read();
        System.out.println(read);//104
        System.out.println((char) read);//h

        //第二次读取数据
        read = fis.read();
        System.out.println(read);//101
        System.out.println((char) read);//e*/

        //循环改造读取字节
        /*int read = fis.read();
        while (read!=-1){
            System.out.print((char) read);
            read = fis.read();
        }*/

        //优化上面的代码---字节流读数据的标准代码
        int read;
        while ((read=fis.read())!=-1){
            System.out.print((char) read);
        }
        //释放资源
        fis.close();
    }
}

7. 案例:字节流复制文本文件

需求:把D:\\Java\\java.txt复制到模块目录下的fos2.txt

分析:

①:复制文本文件,其实就是把文本文件的内容从一个文件中读出来(数据源),然后写入另一个文件中(目的地)。

②:数据源:

  • D:\\Java\\java.txt——–读数据-------------InputStream-------FileInputStream

③:目的地

  • Stuay01\\fos2.txt--------写数据-------------OutputStream——-FileOutputStream

思路:

①:根据数据源创建字节输入流对象

②:根据目的地创建字节输出流对象

③:读写数据,赋值文本文件(一次读取一个字节,一次写入一个字节)

④:释放资源

package Study02;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*需求:把`D:\\Java\\java.txt`复制到模块目录下的`fos2.txt`

分析:
①:复制文本文件,其实就是把文本文件的内容从一个文件中读出来(数据源),然后写入另一个文件中(目的地)。
②:数据源:
- `D:\\Java\\java.txt`——–读数据-------------`InputStream`-------`FileInputStream`
③:目的地
- `Stuay01\\fos2.txt`--------写数据-------------`OutputStream`——-`FileOutputStream`

思路:
①:根据数据源创建字节输入流对象
②:根据目的地创建字节输出流对象
③:读写数据,赋值文本文件(一次读取一个字节,一次写入一个字节)
④:释放资源
*/
public class FileInputeStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //①:根据数据源创建字节输入流对象
        FileInputStream fis = new FileInputStream("D:\\Java\\java.txt");
        //②:根据目的地创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("Stuay01\\fos2.txt");
        //③:读写数据,赋值文本文件(一次读取一个字节,一次写入一个字节)
        int read;
        while ((read = fis.read())!=-1){
            fos.write(read);
        }
        //④:释放资源
        fis.close();
        fos.close();

    }
}

8. 字节流读数据(一次读一个字节数组数据)

需求:把文件fos2.txt中的内容读出来在控制台输出

使用字节输入流读数据的步骤:

①:创建字节输入流对象

②:调用字节输入流对象的读数据方法

③:释放资源

package Study02;

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

/*需求:把文件`fos2.txt`中的内容读出来在控制台输出

使用字节输入流读数据的步骤:
①:创建字节输入流对象
②:调用字节输入流对象的读数据方法
③:释放资源*/
public class FileOutputStreamDemo02 {
    public static void main(String[] args) throws IOException {
        //①:创建字节输入流对象
        FileInputStream fis = new FileInputStream("Stuay01\\fos2.txt");
        //②:调用字节输入流对象的读数据方法
        byte[] bytes = new byte[1024];//长度一般为1024或1024的整数倍
        int len;
        //当长度为-1时代表已经读到了最后
        while ((len = fis.read(bytes))!=-1){
            //String(byte[] bytes, int offset, int length) 
            //通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。  
            System.out.print(new String(bytes,0,len));
        }
        //③:释放资源
        fis.close();
    }
}

9. 案例:复制图片

需求:把D:\\Java\\ml.png复制到模块目录下的ml.png

  1. 思路:
    • 根据数据源创建字节输入流对象
    • 根据目的地创建字节输出流对象
    • 读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
    • 释放资源
package Study02;

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

/*需求:把`D:\\Java\\ml.png`复制到模块目录下的`ml.png`

1. 思路:
	- 根据数据源创建字节输入流对象
	- 根据目的地创建字节输出流对象
	- 读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
	- 释放资源*/
public class FileInputStreamDemo02 {
    public static void main(String[] args) throws IOException {
        //根据数据源创建字节输入流对象
        FileInputStream fis = new FileInputStream("D:\\\\Java\\\\ml.png");
        //根据目的地创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("Stuay01\\ml.png");
        //读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
        byte[] bytes = new byte[1024];
        int len;
        while ((len = fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
        //释放资源
        fis.close();
        fos.close();
    }
}

10.字节缓冲流

  1. 字节缓冲流:

    • BufferedOutputStream:该类实现缓冲输出流。通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。
    • BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。
  2. 构造方法

    • 字节缓冲输出流:BufferedOutputStream(OutputStream out)
    • 字节缓冲输入流:BufferedInputStream(InputStream in)
  3. 为什么构造方法需要的是字节流,而不是具体的文件或路径呢?

    • 字节缓冲流仅仅是提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作。
package Study03;

import java.io.*;

/*1. 字节缓冲流:
	- BufferedOutputStream
	- BufferedInputStream

2. 构造方法
	- 字节缓冲输出流:`BufferedOutputStream(OutputStream out)`
	- 字节缓冲输入流:`BufferedInputStream(InputStream in)`
	*/
public class BuffereStreamDemo {
    public static void main(String[] args) throws IOException {
        //- 字节缓冲输出流:`BufferedOutputStream(OutputStream out)`
        /*FileOutputStream fos = new FileOutputStream("Stuay01\\bos.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);*/
        //--合为一步解决--
        /*BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Stuay01\\bos.txt"));
        //写数据
        bos.write("hello\r\n".getBytes());
        bos.write("world\r\n".getBytes());
        //释放资源
        bos.close();
*/

        //- 字节缓冲输入流:`BufferedInputStream(InputStream in)`
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("Stuay01\\bos.txt"));
        //读数据
        //一次读一个字节数据
        /*int by;
        while ((by=bis.read())!=-1){
            System.out.print((char) by);
        }
        bis.close();
        */
        //一次读一个字节数组数组
        byte []bytes = new byte[1024];
        int len;
        while ((len=bis.read(bytes))!=-1){
            System.out.print(new String(bytes,0,len));
        }
        //释放资源
        bis.close();
    }
}

11. 案例:复制视频

需求:把D:\\Java\\153_IO流小结.mp4复制到模块目录下的Stuay01\\153_IO流小结.mp4

思路:

① 根据数据源创建字节输入流对象

② 根据目的地创建字节输出流对象

③ 读写数据,复制视频

④ 释放资源

package Study03;
import java.io.*;
/*需求:把`D:\\Java\\153_IO流小结.mp4`复制到模块目录下的`Stuay01\\153_IO流小结.mp4`

思路:
① 根据数据源创建字节输入流对象
② 根据目的地创建字节输出流对象
③ 读写数据,复制视频
④ 释放资源

1. 四种方式实现复制视频,并记录每种方式复制视频的时间
	- 基本字节流一次读写一个字节         花费35530毫秒
	- 基本字节流一次读写一个字节数组      花费62毫秒
	- 字节缓冲流一次读写一个字节          花费了183毫秒
	- 字节缓冲流一次读写一个字节数组       花费了22毫秒
	*/
public class BuffereStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //记录开始时间
        long startTime = System.currentTimeMillis();
        //读写数据,复制视频
//        method1();//基本字节流一次读写一个字节总共花费35530毫秒
//        method2();//基本字节流一次读写一个字节数组总共花费了62毫秒
//        method3();//字节缓冲流一次读写一个字节总共花费了183毫秒
        method4();//字节缓冲流一次读写一个字节数组总共花费了22毫秒

        //记录结束时间
        long enfTime = System.currentTimeMillis();
        System.out.println("总共花费了" + (enfTime - startTime) + "毫秒");

    }
    //基本字节流一次读写一个字节
    public static void method1() throws IOException{
        FileInputStream fis1 = new FileInputStream("D:\\Java\\153_IO流小结.mp4");
        FileOutputStream fos1 = new FileOutputStream("Stuay01\\\\153_IO流小结.mp4");
        int by;
        while ((by=fis1.read())!=-1){
            fos1.write(by);
        }
        fis1.close();
        fos1.close();
    }

    //基本字节流一次读写一个字节数组
    public static void method2() throws IOException{
        FileInputStream fis2 = new FileInputStream("D:\\Java\\153_IO流小结.mp4");
        FileOutputStream fos2 = new FileOutputStream("Stuay01\\\\153_IO流小结.mp4");
        byte []bytes = new byte[1024];
        int len;
        while ((len=fis2.read(bytes))!=-1){
            fos2.write(bytes,0,len);
        }
        fis2.close();
        fos2.close();
    }

    //字节缓冲流一次读写一个字节
    public static void method3() throws IOException{
        BufferedInputStream bis1 = new BufferedInputStream(new FileInputStream("D:\\Java\\153_IO流小结.mp4"));
        BufferedOutputStream bos2 = new BufferedOutputStream(new FileOutputStream("Stuay01\\\\153_IO流小结.mp4"));
        int by;
        while ((by = bis1.read())!=-1){
            bos2.write(by);
        }
        bos2.close();
        bis1.close();
    }

    ////字节缓冲流一次读写一个字节数组
    public static void method4() throws IOException{
        BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream("D:\\Java\\153_IO流小结.mp4"));
        BufferedOutputStream bos2 = new BufferedOutputStream(new FileOutputStream("Stuay01\\\\153_IO流小结.mp4"));
        byte[]bytes=new byte[1024];
        int len;
        while ((len = bis2.read(bytes))!=-1){
            bos2.write(bytes,0,len);
        }
        bos2.close();
        bis2.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

幺洞两肆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值