Day20JavaSE——IO流之字节流

Day20JavaSE——IO流之字节流

IO流概述

A:IO流概述
	IO流用来处理设备之间的数据传输
	Java对数据的操作是通过流的方式
	Java用于操作流的对象都在IO包中 java.io
B:IO流分类
	a:按照数据流向 站在内存角度
		输入流	读入数据
		输出流	写出数据
	b:按照数据类型
		字节流 可以读写任何类型的文件 比如音频 视频  文本文件
		字符流 只能读写文本文件
		什么情况下使用哪种流呢?
		如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流。其他用字节流。
		如果你什么都不知道,就用字节流

字节流的抽象基类

A:IO流基类概述
	a:字节流的抽象基类:
		InputStream ,OutputStream。
	b:字符流的抽象基类:
		Reader , Writer。
	注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
	如:InputStream的子类FileInputStream。
	如:Reader的子类FileReader。
B:FileOutputStream的构造方法
	由一个案例引出使用IO流写数据,由于字节流先出现就先学习字节输出流基类OutputStream,
	使用具体子类FileOutputStream

FileOutputStream&FileInputStream

FileOutputStream

public class Test1 {
    public static void main(String[] args) throws IOException {
        //FileOutputStream:文件输出流是用于将数据写入File
        //按住ctrl点击添加书签
        /*
        * FileOutputStream(File file)
        * 创建文件输出流以写入由指定的 File对象表示的文件。
        * FileOutputStream(File file, boolean append)
        * 创建文件输出流以写入由指定的 File对象表示的文件。
        * 如果第二个参数是true ,则字节将被写入文件的末尾而不是开头,也就是追加写入,不会覆盖原内容
        * FileOutputStream(FileDescriptor fdObj)
        * 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
        * FileOutputStream(String name)
        * 创建文件输出流以指定的名称写入文件。
        * FileOutputStream(String name, boolean append)
        * 创建文件输出流以指定的名称写入文件。如果第二个参数是true
        * 则字节将写入文件的末尾而不是开头,也就是追加写入,不会覆盖原内容
        * */
        //创建一个文件对象
        File file = new File("a.txt");
        //创建刚还文件对象的文件输出流
        FileOutputStream outa = new FileOutputStream(file);
        //创建文件输出流以指定的名称写入文件,这个构造函数会自动新建一个文件
        FileOutputStream outb = new FileOutputStream("b.txt");
        //创建文件输出流以指定的名称写入文件,字节写入文件的开头
        FileOutputStream outc = new FileOutputStream("c.txt", false);
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要写入的内容");
        String s = sc.nextLine();
        //若要写入中文或一个字符串,就需要调用String类中的getByte函数
        //将字符串提取为byte类型
        byte[] writeText= s.getBytes();
        /*void write(byte[] b)
        将 b.length个字节从指定的字节数组写入此文件输出流。
        void write(byte[] b, int off, int len)
        将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。
        void write(int b)
        将指定的字节写入此文件输出流。*/
        //一次写入一个字节,超出一个字节就会丢弃掉多余字节
        outa.write(6);
        outb.write('c');
        //将转换好的字符串放入字节数组中,再调用write函数写入文件内
        outc.write(writeText);
        //最后要关闭
        /*void close()
        关闭此文件输出流并释放与此流相关联的任何系统资源。*/
        outa.close();
        outb.close();
        outc.close();
    }
}
public class Test2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream out1 = new FileOutputStream("d.txt");
        //往文件中写入数据
        System.out.println("========往文件中写入一个字节========");
        out1.write(97);
        out1.write(100);
        //如果多出一个字节,就会丢弃多余字节
        //out1.write(200);

        System.out.println("=======往文件中写入一个字节数组======");
        FileOutputStream out2 = new FileOutputStream("e.txt");
        //一次写入一个字节数组
        ByteArrayOutputStream baos;
        byte[] write = {94, 95, 96, 97, 98, 99};
        out2.write(write);

        System.out.println("=========往文件中写入一串中文=======");
        FileOutputStream out3 = new FileOutputStream("f.txt");
        String str="会感到十分光滑";
        //字符串需要转换成字节数组才能使用字节流写入
        byte[] chinese = str.getBytes();
        out3.write(chinese);

        System.out.println("===往文件中写入一个字节数组的一部分===");
        FileOutputStream out4 = new FileOutputStream("g.txt");
        String str1="会感到十分光滑";
        //字符串需要转换成字节数组才能使用字节流写入
        byte[] chinese1 = str.getBytes();
        out4.write(chinese1,3,6);

        //流使用完记得要释放资源
        out1.close();
        out2.close();
        out3.close();
        out4.close();

        /*注意事项:
        创建字节输出流对象了做了几件事情 ?
        a : 调用系统资源创建a.txt文件
        b:创建了一个文件对象
        c:把该文件对象指向这个文件
               流使用完毕,为什么一定要close() ?
                a : 通知系统释放关于管理a.txt文件的资源
                b:让Io流对象变成垃圾, 等待垃圾回收器对其回收*/
    }
}
public class Test3 {
    public static void main(String[] args) throws IOException {
        System.out.println("============追加写入============");
        //创建一个不会覆盖原内容的文件及文件对象
        FileOutputStream outputStream = new FileOutputStream("h.txt", true);
        outputStream.write("啊随风倒敢死队风格".getBytes());
        //写入换行符
        /*  windows下的换行符是 \r\n
        Linux \n
        Mac    \r
        */
        outputStream.write("\r\n".getBytes());
        outputStream.write("公司的风格岁的法国".getBytes());
        outputStream.write("\r\n".getBytes());
        outputStream.close();
    }
}
public class Test4 {
    public static void main(String[] args) {
        //流的异常处理
        FileOutputStream out = null;

        try {
            new FileOutputStream("i.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            //如果FileOutputStream对象不是null,则释放资源,否则打印异常信息
            try{
                if(out!=null){
                    out.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

FileInputStream

public class Text1 {
    public static void main(String[] args) {
        /*
        * FileInputStream(File file)
        * 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
        * FileInputStream(FileDescriptor fdObj)
        * 创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
        * FileInputStream(String name)
        * 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。*/
        try {
            FileInputStream in1 = new FileInputStream("d.txt");
            System.out.println("===========读取文件中的数据===========");
            System.out.println("==============读一个字节=============");
            /*int read()
            * 从该输入流读取一个字节的数据。 */

            int read = in1.read();
            System.out.println(read);
            int read1 = in1.read();
            System.out.println(read1);
            //如果读取不到有效的字节,就会返回-1 ,我们经常使用-1来判断这个文件的数据是否读取完毕。
            int read2 = in1.read();
            System.out.println(read2);
            //流使用完毕,释放资源
            in1.close();

            System.out.println("============读一个字节数组============");
            /*int read(byte[] b)
            * 从该输入流读取最多 b.length个字节的数据为字节数组。 */

            FileInputStream in2 = new FileInputStream("h.txt");
            //创建一个字节数组缓存区
            byte[] inBuffer = new byte[1024];
            //把读取的字节,装进传进来的容器中
            //返回的是一次实际读取的有效字节数
            int len = in2.read(inBuffer);
            System.out.println("读取到的有效字节数是" + len);
            System.out.println(Arrays.toString(inBuffer));

            //把读取到的字节数组转化成字符串显示
            java.lang.String s = new java.lang.String(inBuffer, 0, len);
            System.out.println(s);
            //流使用完毕,释放资源
            in2.close();

            System.out.println("============读取有效的字节============");
            /*int read(byte[] b, int off, int len)
            * 从该输入流读取最多 len字节的数据为字节数组.*/
            //一次从文件中读取3个字节,从0索引处开始把读取到的3个字节放入容器中
            //如果读取不到有效字节返回的是 -1

            FileInputStream in3 = new FileInputStream("g.txt");
            //设置缓存区
            byte[] inBuffer2 = new byte[1024];
            int inLen = in3.read(inBuffer2, 0, 6);
            System.out.println("读取到的有效字节个数:" + inLen);
            /*inLen = in3.read(inBuffer2, 0, 6);
            System.out.println("读取到的有效字节个数:" + inLen);*/
            /*有效字节数就是有实际内容的字节
            inLen = in3.read(inBuffer2, 0, 128);
            System.out.println("读取到的有效字节个数:" + inLen);*/
            String s1 = new String(inBuffer2, 0, inLen);
            System.out.println(s1);
            //流使用完毕,释放资源
            in3.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

高效字节输入输出流

public class Test {
    public static void main(String[] args) {
        //高效的字节输入输出流
        //BufferedInputStream
        //BufferedOutputStream
        try {
            test1();//使用单字节复制完成共耗时29146ms
            test2();//复制完成共耗时16933毫秒
            test3();//使用缓存区复制完成共耗时12ms
            test4();//复制完成共耗时12毫秒
            /*同一个文件,当使用字节复制的时候高效流比普通流的使用的时间缩短了一半
            * 但是当使用缓存复制的时候,高效流和普通流使用的时间一样*/
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void test1() throws IOException {
        System.out.println("============使用普通流字节复制============");
        FileInputStream dataInCompare = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3");
        FileOutputStream dataOutCompare = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Test\\Jam - 七月上.mp3");
        int inDataCompare = 0;
        //调用系统函数计算开始复制的时间
        long startCompare = System.currentTimeMillis();
        while ((inDataCompare = dataInCompare.read()) != -1) {
            dataOutCompare.write(inDataCompare);
            dataOutCompare.flush();
        }
        //调用系统函数计算复制复制完成的时间
        long endCompare = System.currentTimeMillis();
        System.out.println("使用单字节复制完成共耗时"+(endCompare-startCompare)+"ms");
        //释放资源
        dataInCompare.close();
        dataOutCompare.close();
    }
    private static void test2() throws IOException {
        System.out.println("============使用高效流字节复制============");
        /*   BufferedInputStream(InputStream in)
        创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。

        BufferedOutputStream(OutputStream out)
          创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
        */
        BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3"));
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Test\\Jam - 七月上.mp3"));
        int by=0;
        long start = System.currentTimeMillis();
        while ((by = in.read()) != -1) {
            out.write(by);
            out.flush();
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完成共耗时" + (end - start) + "毫秒");

        //释放资源
        in.close();
        out.close();
    }
    private static void test3() throws IOException {
        System.out.println("============使用普通流缓存复制============");
        //定义1kb=1024byte的数据,这里开辟了8kb的缓存区
        byte[] dataBuffer = new byte[1024*8];
        FileInputStream dataIn = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3");
        FileOutputStream dataOut = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Jam - 七月上.mp3");
        //定义一个变量,来记录每次读取到的有效字节个数
        int len = 0;
        //调用系统函数计算开始复制的时间
        long start = System.currentTimeMillis();
        //read函数返回的是当前读取到的有效字节数
        while ((len = dataIn.read(dataBuffer)) != -1) {
            //将字节数组缓存区中的数据写入文件
            dataOut.write(dataBuffer,0,len);
            dataOut.flush();
        }
        //调用系统函数计算复制复制完成的时间
        long end = System.currentTimeMillis();
        System.out.println("使用缓存区复制完成共耗时"+(end-start)+"ms");
        //释放资源
        dataIn.close();
        dataOut.close();
    }
    private static void test4() throws IOException {
        System.out.println("============使用高效流缓存复制============");
        BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3"));
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Jam - 七月上.mp3"));

        //一次读取一个字节,写入一个字节来复制mp3
        byte[] bytes = new byte[1024 * 8];
        int by = 0;
        long start = System.currentTimeMillis();
        while ((by = in.read(bytes)) != -1) {
            out.write(bytes,0,by);
            out.flush();
        }
        long end = System.currentTimeMillis();

        System.out.println("复制完成共耗时" + (end - start) + "毫秒");
        //释放资源
        in.close();
        out.close();
    }
}

字节流复制文件

复制文本文件&MP3文件

public class Test1 {
    public static void main(String[] args) {
        try {
            System.out.println("============方式一============");
            //一个字节一个字节的复制
            FileInputStream in = new FileInputStream("h.txt");
            FileOutputStream out = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\h.txt");
            int data = 0;
            while ((data = in.read()) != -1) {
                out.write(data);
                out.flush();
            }
            //释放资源
            in.close();
            out.close();

            System.out.println("============方式二============");
            /*1byte=8bit
            * 1kb=1024byte
            * 1M=1024kb
            * 1G=1024M
            * 1T=1024G*/
            //一次复制一个字节的数据过于缓慢
            //如果要复制一个1M大小的MP3文件的话
            //一次复制一个字节的数据就会不停地读写1024的平方次
            //要是我们读写的文件大小是NM,则复制文件的时间复杂度为O(N*1024*1024)
            //所以此处我们引入缓存区的概念
            //一次缓存1024*1024byte=1M的数据,这样时间复杂度相对于O(N)就可以看成是O(1)

            System.out.println("============缓存区复制============");
            //定义1kb=1024byte的数据,这里开辟了8kb的缓存区
            byte[] dataBuffer = new byte[1024*8];
            FileInputStream dataIn = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3");
            FileOutputStream dataOut = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Jam - 七月上.mp3");
            //定义一个变量,来记录每次读取到的有效字节个数
            int len = 0;
            //调用系统函数计算开始复制的时间
            long start = System.currentTimeMillis();
            //read函数返回的是当前读取到的有效字节数
            while ((len = dataIn.read(dataBuffer)) != -1) {
                //将字节数组缓存区中的数据写入文件
                dataOut.write(dataBuffer,0,len);
                dataOut.flush();
            }
            //调用系统函数计算复制复制完成的时间
            long end = System.currentTimeMillis();
            System.out.println("使用缓存区复制完成共耗时"+(end-start)+"ms");
            //释放资源
            dataIn.close();
            dataOut.close();

            System.out.println("==========单字节复制同一个文件==========");
            FileInputStream dataInCompare = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\复试资料\\Jam - 七月上.mp3");
            FileOutputStream dataOutCompare = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\Test\\Jam - 七月上.mp3");
            int inDataCompare = 0;
            //调用系统函数计算开始复制的时间
            long startCompare = System.currentTimeMillis();
            while ((inDataCompare = dataInCompare.read()) != -1) {
                dataOutCompare.write(inDataCompare);
                dataOutCompare.flush();
            }
            //调用系统函数计算复制复制完成的时间
            long endCompare = System.currentTimeMillis();
            System.out.println("使用单字节复制完成共耗时"+(endCompare-startCompare)+"ms");
            //释放资源
            dataInCompare.close();
            dataOutCompare.close();

            /*由以上我们可以看到,复制大文件,合适的缓存区能够大量的减少代码的时间复杂度*/
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

异常处理

public class Test2 {
    public static void main(String[] args) {
        //流的异常处理
        FileInputStream dataIn=null;
        FileOutputStream dataOut=null;
        try {
            dataIn = new FileInputStream("C:\\Users\\adair_liu\\Desktop\\Java\\MyNote\\Java笔记\\Day19JavaSE——IO概述&异常&File文件类\\04视频\\录像160.mp4");
            dataOut = new FileOutputStream("C:\\Users\\adair_liu\\Desktop\\录像160.mp4");
            //1、定义字节数组充当缓冲区
            byte[] dataBuffer = new byte[1024];
            //2.定义一个变量。用来记录每次读取到的有效字节个数
            int len=0;
            //3.频繁的读写
            long start = System.currentTimeMillis();
            while ((len = dataIn.read(dataBuffer)) != -1) {
                dataOut.write(dataBuffer,0,len);
                dataOut.flush();
            }
            long end = System.currentTimeMillis();
            System.out.println("复制完成共耗时" + (end - start) + "毫秒");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try{
                if(dataIn!=null){
                    dataIn.close();
                }
                if(dataOut!=null){
                    dataOut.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

em.currentTimeMillis();
System.out.println(“复制完成共耗时” + (end - start) + “毫秒”);
} catch (IOException e) {
e.printStackTrace();
}finally {
try{
if(dataIn!=null){
dataIn.close();
}
if(dataOut!=null){
dataOut.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值