JavaSE——IO流-字节流

8 篇文章 0 订阅
7 篇文章 0 订阅

IO流概述及其分类

概述
IO流:用于处理设备之间的数据传输。
Java对数据的操作都是通过流的方式。
Java用于操作流的对象都在IO包中。

分类

  1. 按照数据流向分类

    输入流:读入数据
    输出流:写出数据
    这里的输入和输出指的是内存的输入和输出。

  2. 按照数据类型分类

    字节流:可以读写任何类型的文件,比如音频,视频,文本文件,可执行文件等。
    字符流:只能读写文本文件

    通常情况下,如果文件可以用Windows自带的记事本打开,就可以选用字符流,如果对文件类型不了解的话,就用字节流。

IO流基类概述:

  • 字节流的抽象基类:InputStream OutputStream

  • 字符流的抽象基类:Reader Writer

    字节流
      				字节输入流	InputStream		读
      				字节输出流	OutputStream	写
    字符流
      				字符输入流 	Reader			读
      				字符输出流	Writer			写
    

由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。比如InputStream的子类FileInputStream,Reader的子类FileReader。

OutputStream是一个抽象类,我们不能对其进行直接实例化,而我们需要使用子类对其进行实例化。
我们先来尝试在一个文件里写入文字。
我们现在操作的是文件所以我们选择的是FileOutputStream。
我们先来学习最简单的构造和使用吧。

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

public class Demo {
    public static void main(String[] args) throws IOException {
        File file = new File("a.txt");
        //FileOutputStream(File file)
        //创建一个向指定 File 对象表示的文件中写入数据的文件输出流
        FileOutputStream out = new FileOutputStream(file);
        //FileOutputStream(String name)
        //创建一个向具有指定名称的文件中写入数据的输出文件流。
        //直接传入一个字符串的文件路径,如果这个文件不存在,会自动帮你创建
        FileOutputStream out2 = new FileOutputStream("c.txt");
		 //通过以上两种方式我们就创建了两个FileOutputStream实例
        //接下来我们就可以利用实例来往它所关联的文件里面写入数据
        
        //一次写入一个字节
        /*public void write(int b)*/
        out.write(97);//a
        out.write(98);//b
        out.write(99);//c
        
        //一次写入一个字节数组
        /*public void write ( @NotNull byte[] b)*/
        out2.write("云且舒卷".getBytes());
        
		//写入指定长度的字节
		 /*public void write(@NotNull byte[] b,
                  int off,
                  int len)
                  将字节数组从off位置开始len长度字节数组数据写入到输出流
		*/
        //用Stringl类的转换方法getBytes()把字符串转化成字符数组
        String s="月也含羞";
        out2.write(s.getBytes(), 0, s.length);
        //UTF - 8 不是固定字长编码的,而是一种变长的编码方式,一个汉字三个字节
        
        //流使用完之后,必须释放资源
        out.close();
        out2.close();
    }
}

上面的代码可以帮助我们在指定的文件中写入数据,那么,创建字节输出流对象做了几件事情呢?

  1. 调用系统资源创建a.txt文件
  2. 创建一个fos对象
  3. 把fos对象指向这个文件

为什么一定要close()?

  • 通知系统释放关于管理a.txt文件的资源
  • 让IO流对象变成垃圾,等待垃圾回收器对其回收

FileOutputStream写出数据实现数据的换行

import java.io.FileOutputStream;
import java.io.IOException;
public class Demo2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream out = new FileOutputStream("d.txt");
        //写入换行符
        //windows下的换行符      \r\n
        // Linux		       \n
        // Mac		           \r
        out.write("爱情".getBytes());
        out.write("\r\n".getBytes());
        out.write("亲情".getBytes());
        out.write("\r\n".getBytes());
        out.write("定义".getBytes());
        out.write("\r\n".getBytes());
        out.close();
    }
}

FileOutputStream写出数据实现数据的追加写入

import java.io.FileOutputStream;
import java.io.IOException;
public class Demo2_1{
	public static void main(String[] args){
		/*FileOutputStream(File file, boolean append)*/
		/*FileOutputStream(String name, boolean append)*/
		// 完成追加写入
		FileOutputStream fos = new FileOutputStream("fos.txt" , true) ;  
		// 写数据
		for(int x = 0 ; x < 10 ; x++){
			fos.write(("hello" + x).getBytes()) ;
			fos.write("\r\n".getBytes()) ;
		}
		// 释放资源
		fos.close();
	}
}

FileInputStream的构造与使用

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

public class Demo3 {
    public static void main(String[] args) throws IOException {
        //   FileInputStream 从文件系统中的某个文件获得输入字节
        //   构造方法和FileOutputStream类似
        /*FileInputStream(String name)
         * 通过打开一个到实际文件的连接来创建一个 FileInputStream
         * 该文件通过文件系统中的路径名 name 指定。*/
        /*FileInputStream(File file)
         * 通过打开一个到实际文件的连接来创建一个 FileInputStream
         * 该文件通过文件系统中的 File 对象 file 指定。*/

        //输入流,如果所关联的文件不存在,那么就会报错
        //我们之前不是创建了几个文件吗,现在就用他们来演示
        FileInputStream in = new FileInputStream("d.txt");
        //那么我们现在就来读取文件中的数据

        //1、一次读取一个字节,如果读取不到字节数据返回 -1
        //int len = in.read();
        //System.out.println(len);

        //2、一次读取一个字节数组
        byte[] bytes = new byte[1024];//缓冲区
        //返回值是你读取到有效字节个数
        //int len1 = in.read(bytes);
        //System.out.println(len1); //111
        //可以把这个字节数组转成字符串来打印
        //String s = new String(bytes, 0, len1);
        //System.out.println(s);
        /*爱情
          亲情
          定义*/

        //3.一次取字节数组的一部分
        int len2 = in.read(bytes, 0, 6);
        //off代表读取到的字节数据往缓存区bytes放的时候,从哪个位置开始,len表示一次读取几个字节
        System.out.println(len2);//6
        String s = new String(bytes, 0, len2);
        System.out.println(s);//我和

        //for (byte aByte : bytes) {
        //    System.out.println(aByte);
        //}

        //    释放资源
        in.close();

    }
}

FileOutputStream写出数据加入异常处理

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

public class Demo4 {
    public static void main(String[] args) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream("e.txt");
            out.write("怎么处理".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //不管try里面有没有遇到异常,finally里面的代码都会执行
            //一般我们在finally里面做一些善后工作,比如释放一些资源
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

字节流复制文本文件

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

public class Demo5 {
    public static void main(String[] args) throws IOException {
        //    方式一:一次读写一个字节来复制文本文件
        //    我们把前面写好的文本d.txt复制到D盘
        FileOutputStream out = new FileOutputStream("D:\\d.txt");
        FileInputStream in = new FileInputStream("d.txt");
        int len = 0;
        while ((len = in.read()) != -1) {
            out.write(len);
        }
        //释放资源
        in.close();
        out.close();
    }
}

字节流复制MP3(一次一个字节)

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

public class Demo5_1 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream("E:\\我的图片和音乐\\音乐\\许巍 - 曾经的你.mp3");
        FileOutputStream out = new FileOutputStream("D:\\曾经的你.mp3");
        int len = 0; //记录读取到的字节
        while ((len = in.read()) != -1) {
            out.write(len);
            out.flush();//刷新刷新!!!
        }
        /*关闭(close) 输出流时,应先刷新(flush)缓冲的输出流,
        换话句话说:“迫使所有缓冲的输出数据被写出到底层输出流中”*/
        //记得释放资源
        in.close();
        out.close();
    }
}

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

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*int read(byte[] b):一次读取一个字节数组
返回的int类型的值表示的意思是读取到的字节的个数,如果没有数据了就返回-1*/
public class Demo5_2 {
    public static void main(String[] args) throws IOException {
        //一次读写一个字节效率不高,一般不采用
        //一般我们采用一次读写一个字节数组
        FileInputStream in = new FileInputStream("E:\\我的图片和音乐\\疯狂动物城.mp4");
        FileOutputStream out = new FileOutputStream("D:\\疯狂动物城.mp4");
        //创建一个数组缓冲区
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = in.read(bytes)) != -1) {
            out.write(bytes);
            out.flush();
        }
        in.close();
        out.close();
    }
}

BufferedInputStream和BufferedOutputStream处理数据

通过定义数组读取明显比每次读写一个字节来得快,有个数组来做缓冲区很管用, java想到了这个问题,就提供了 带缓冲区的字节类。

构造方法

  • BufferedOutputStream(OutputStream out)
    创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
  • BufferedOutputStream(OutputStream out, int size)
    创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。

从构造方法中我们可以知道BufferedOutputStream没有无参构造方法,它必须传入一个OutputStream(一般是FileOutputStream),来一起使用,以提高读写效率。
它只是一个缓冲区,真正的操作还是要靠流来进行,只是用它做个容器。

import java.io.*;
public class Demo5_3 {
    public static void main(String[] args) throws IOException {
        //BufferedInputStream BufferedOutputStream
        //更加高效的字节输入输出流
        /*BufferedOutputStream(OutputStream out
         *创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
         *BufferedOutputStream(OutputStream out, int size)
         *创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。
         * */
        BufferedInputStream in = new BufferedInputStream(new FileInputStream("E:\\我的图片和音乐\\疯狂动物城.mp4"));

        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\疯狂动物城.mp4"));

        byte[] bytes = new byte[1024 * 8];
        int len = 0;
        while ((len = in.read(bytes)) != -1) {
            out.write(bytes);
            out.flush();
        }
        out.close();
        in.close();

    }
}

一次性复制多个文件

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

public class Demo6 {
    public static void main(String[] args) throws IOException {
        //一次复制多个文件
        FileInputStream in = new FileInputStream("D:\\宇多田ヒカル - Prisoner Of Love.mp3");
        FileOutputStream out1 = new FileOutputStream("E:\\宇多田ヒカル - Prisoner Of Love1.mp3");
        FileOutputStream out2 = new FileOutputStream("E:\\宇多田ヒカル - Prisoner Of Love2.mp3");
        ArrayList<FileOutputStream> list = new ArrayList<>();
        list.add(out1);
        list.add(out2);
        byte[] bytes = new byte[1024 * 8];
        int len = 0;
        while ((len = in.read(bytes)) != -1) {
            for (FileOutputStream outputStream : list) {
                outputStream.write(bytes);
                outputStream.flush();
            }
        }
        in.close();
        out1.close();
        out2.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值