栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

【全网最全】JAVA IO流

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【全网最全】JAVA IO流

1.IO流

以后开发中会遇到文件的上传和下载,都是需要用到IO流

咱们电脑上面所有的文件, 文档 音频 图片 视频 等都是可以进行读和写的。他们咋读的?

咋写的? 一下子就写到咱们项目中了吗?不是,依靠流的形式进行读 和写。很抽象

在读取的时候,会将咱们的文件(音频 视频 等)变成流的形式 一点一点来处理的 拆解开来出来的。

1.1缓冲的概念

看视频有点卡?暂停一下,加载缓冲一下。

快递:送到物流中转站,然后分批次的发。物流中转站就是缓冲的概念。

IO流 的本质就是对电脑的文件进行读和写的

计算机通过CPU内存读取磁盘上面的文件数据,一次读取1字节。但是可以加上缓冲的概念

每次读取4kb。效率会高点的,咱们可以测试一下。效率是不是确实高了。

1.2IO流的分类

咱们今天的学习紧紧围绕着:

1.从磁盘读取数据到内存(Java代码) 磁盘=》代码中 输入流

2.从内存(Java代码 String str = "狗蛋很帅")写入数据到磁盘某一个文件 代码=》磁盘 输出流

参照物:是内存,就是Java代码。

输入流: 从磁盘读取到内存

输出流:从内存写入到磁盘

I:

input: 输入 从磁盘读取数据到内存

使用input输入流的应用场景是啥:比如 磁盘上面有一个1.txt文件,将1.txt文件的内容读取到Java内存中。使用的是输入流。

输入流分为两种:

1.字节输入流 FileInputStream

2.字符输入流

输出流分为两种:

1.字节输出流 FileOutputStream

2.字符输出流

1.2.1字节输入流

讲一个新的知识点,你最起码先知道这个知识点能干嘛?

字节输入流:磁盘上面有一个1.txt文件,现在要将1.txt文件中的内容读取到内存(Java代码中)

Java给咱们封装好了类: FileInputStream 文件输入流(字节输入流)

package com.qfedu.a_fileinputstream;

import java.io.*;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //将磁盘上面的c:/aaa/1.txt文件这个数据读取到内存(Java)中
        //加上缓冲的效果,这种很牛逼啊,将磁盘上面的东西弄到咱们Java代码中
        //1.创建File对象,是咱们本地磁盘文件的一个File对象
        //为啥要创建这个File对象?因为要读取1.txt这个文件的里面的
        //内容,首先先找到文件再说啊。
        File file = new File("c:/aaa/1.txt");
        //2.创建文件字节输入流对象,来操作1.txt
        //FileInputStream(File file)
        //通过打开与实际文件的连接创建一个 FileInputStream ,
        // 该文件由文件系统中的 File对象 file命名。
        //将c:/aaa/1.txt文件转为字节输入流的形式,之后可以按照流的形式读取到内存中
        FileInputStream fis = new FileInputStream(file);
        //3.fileInputStream 这个流不具备缓冲的效果。
        //但是加上缓冲的效果!!! 咋办?使用另外一个流
        //BufferedInputStream
        //A BufferedInputStream为另一个输入流添加了功能,即缓冲输入
        //咋加?将FileInputStream传给BufferedInputStream 此时
        //FileInputStream  就具备缓冲的功能了!!!
        BufferedInputStream bis = new BufferedInputStream(fis);
        //使用字节缓冲流操作咱们的1.txt
        //当创建BufferedInputStream时,
        // 将创建一个内部缓冲区数组,这个数组是什么数据类型的?
        //5.创建一个缓冲区的数组  byte  为啥是byte类型的数组
        //因为是字节输入流  所以是byte  byte 就是字节
        //当缓冲数组是2个字节的时候,每次读取的时候存到缓冲数组中,只存2个字节
        //发现数据一次性读取不完?咋办?咋解决?
        byte[] buf = new byte[1024 * 4];//缓冲区4096字节
        //现在数组是空的
        //6.读取数据
        //public int read(byte[] b)
        //         throws IOException
        //从输入流读取一些字节数,并将它们存储到缓冲区b 。
        // 实际读取的字节数作为整数返回
        //将1.txt文件的内容 读取到缓冲数组中  buf 里面
        //之前buf是一个空的数组,现在通过read方法将1.txt文件中的
        //内容读取到了 buf空的数组中
//        int read = bis.read(buf);
//        System.out.println(read);
        //6.调用read方法之后,buf 数组就有值了 能不能打印一下
        //借助于String类来展示byte数组的内容
        //buf  给字符串  为了展示字节数组中的内容的
        //0 偏移量   buf这个数组中从哪开始取值  从下标为0 的地方取值
        //read  取6个
        //如果b的长度为零,则不会读取字节并返回0 ;
        // 否则,尝试读取至少一个字节。
        // 如果没有字节可用,因为流在文件末尾,则返回值-1
        int length = -1;
        //如果length=-1  那么就会到达流的末尾  就证明后面没哟数据
        //循环结束,不要再读了
        while ((length = bis.read(buf)) != -1) {
            //循环4次
            System.out.println("狗蛋");
            //数组中的东西要展示出来  使用String
            //将磁盘上面的内容 读取到 =》 内存  buf
            System.out.println(new String(buf, 0, length));
        }
        //7.流是需要关闭的
        bis.close();
        fis.close();



    }
}

知道字节输入流是干嘛的?可以将磁盘上面的某一个文件读取到Java代码中(内存)

固定的写法!!!但是你得知道每行代码是啥意思

package com.qfedu.a_fileinputstream;

import java.io.*;

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //1.创建File对象
        File file = new File("c:/aaa/7.txt");
        //2.创建字节输入流,将7.txt扔给  fis对象了
        FileInputStream fis = new FileInputStream(file);
        //3.创建字节缓冲流, fis又扔给 bis了  现在咱们的数据在bis里面了

        BufferedInputStream bis = new BufferedInputStream(fis);
        //4.声明一个缓冲数组,将bis里面的数据读取出来 赋值给这个
        //缓冲数组
        byte[] buf = new byte[4 * 1024];//4096字节
        //5.开始使用read方法进行读取,读取的时候使用while循环

        //如果7.tx文件中的字节数超过了4096个字节,需要使用循环,再次的读取
        int length;
        //现在数据都在bis里面,咱们要把bis里面的数据读取buf这个数组中
        while ((length = bis.read(buf)) != -1) {
            //byte数组有值以后,咱们可以打印一下看看byte数组中的数据
            System.out.println("循环执行");
            //将字节数组转为字符串,的目的是为了看一下字节数组中的数据
            //并没有实际的意义
            System.out.println(new String(buf, 0, length));
        }
        //6.关闭流
        bis.close();
        fis.close();



    }
}

案例:读取你们盘符下面的一个txt文档,打印在idea控制台。写完以后,将代码直接发到扣扣群里

好好想想这个流程是咋走的?

想象咱们班门口放了一袋大米(就是磁盘的本地文件,文件的内容),现在我要求把门口给我运到我的讲台(Java的内存),不能使用袋子直接搬运?

你们咋解决?可以找一个杯子(就是缓冲数组)。一杯子一杯子的运。能接受不?

比如磁盘上面的380字节的数据, 咋把读取到内存中? 弄一个缓冲数组,每次读取3字节

BufferedInputStream 其实FileInputStream其实一次读取一个字节的,但是使用BufferedInputStream 了之后,可以搞一个缓冲的数组,一次可以读取多个,那么循环次数就会减少,代码的效率就会提升。循环1000遍 和循环1遍的效率 循环1遍的效率,下午演示 加缓冲流和不加缓冲流哪个效率高。

abcdefg

每次读取3个字节
第一次  abc
while (length = 3 != -1) { true
	sout(abc)
}
第二次 def
while (length = 3 != -1) {true
	sout(def)
}
第三次 
while ((length = 1)!= -1 ) {true
	sout(g)new String(buf, 0, 1)
}
当到达文件的末尾的时候, 后面没有东西了,文件的末尾了,到达流的末尾了。返回值是-1
while ((length = -1) != -1) { false 循环结束
	sout(abc)
}

1.2.2字节输出流

将Java中数据写入到磁盘上面

内存-》磁盘 输出流

讲什么案例? 比如Java代码中有一个字符串 String str = "唉,愁人";将这个字符串写入磁盘某一个文件中

FileOutputStream

package com.qfedu.b_fileoutstream;

import java.io.*;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //将Java代码中的一个字符串写入到咱们的磁盘的某一个文件中
        //1.创建File对象,文件路径对象  告知编译器要把数据写到哪个文件中
        File file = new File("c:/aaa/2.txt");
        //2.实例化字节输出流对象
        FileOutputStream fos = new FileOutputStream(file);
        //3.对FileOutputStream  加上缓冲的效果
        //猜测一下  FileInputStream所对应的缓冲流  BufferedInputStream
        //FileOutputStream  所对应的缓冲流  BufferedOutputStream
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //4.将一个字符串写入到磁盘中
        String str = "大家再等我一天,后天见面!!!";
        //	write(byte[] b)
        //咱们的参数是字节数组,咋办?str是一个字符串 但是参数是一个字节数组,咋解决?
        //str是字符串 不能强转  将字符串转为字节数组,没有讲过!!!
        //将str字符串转为字节数组
        byte[] bytes = str.getBytes();
        bos.write(bytes);
        //5.写完以后一定要刷新流然后关闭流
        bos.flush();//没有实际的意义,可以不写的
        //6.关闭流
        //在输入流的时候一定是先开的后关,后开的先关
        bos.close();
        fos.close();




    }
}
package com.qfedu.b_fileoutstream;

import java.io.*;

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //将内容写入到3.txt文件中
        File file = new File("c:/aaa/3.txt");
        FileOutputStream fos = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //开始写了
        //void write(int b);
        //传参是一个int类型,但是真正写入的时候是int类型所对应的字符
        bos.write(97);//开发不用!!!
        bos.flush();
        bos.close();
        fos.close();


    }
}
package com.qfedu.b_fileoutstream;

import java.io.*;

public class Demo3 {
    public static void main(String[] args) throws IOException {
        File file= new File("c:/aaa/4.txt");
        FileOutputStream fos = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        String str = "abcdefg";//7个字节
        //write(byte[] b,int off,int len)
        byte[] bytes = str.getBytes();
        //写一个到缓冲流  从0开始偏移  写入2个字节

        //可以借助于循环往里面写!!!
        bos.write(bytes, 0, 2);//ab
        bos.write(bytes, 2, 2);//cd
        bos.write(bytes, 4, 2);//ef
        bos.write(bytes, 6, 1);//ef
        bos.flush();
        bos.close();
        fos.close();

    }
}
package com.qfedu.b_fileoutstream;

import java.io.*;

public class Demo4 {
    public static void main(String[] args) throws IOException {

        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("c:/aaa/4.txt")));
        bos.write("xixida".getBytes());
        bos.flush();
        bos.close();

    }
}

针对于咱们的讲的字节输入流和字节输出流来一个案例

将c:/bbb文件夹下面一个视频 (源文件) 复制到c:/aaa文件夹下面

思路:将bbb文件夹下面的视频先读取到内存,然后再从内存写入磁盘aaa文件夹下面

缓冲数组  byte[] buf = new byte[4];
视频由字节组成的 一次读取 4096字节  直到最后一次 不一定4096字节
最后一次3456  字节   write(buf, 0, 3456)
相当与将所有字节重新拼接了一下
读取的时候每次读取4096个放到咱们的缓冲数组中,然后立马写入另外磁盘文件下面
直到读取完,写入完即可


qwertyuiopasd  13字节

//第一循环
while ((length=bis.read(buf)) != -1) {//buf 里面 有 qwer
	bos.write(buf, 0, 4);  文本里面有  qwer
}
第二次循环
while ((length=bis.read(buf)) != -1) {//buf 里面 有 tyui
	bos.write(buf, 0, 4);  文本里面有  qwertyui
}
第三次循环
while ((length=bis.read(buf)) != -1) {//buf 里面 有 opas
	bos.write(buf, 0, 4);  文本里面有  qwertyuiopas
}
第四次循环
while ((length=bis.read(buf)) != -1) {//buf 里面 有 d
	bos.write(buf, 0, 1);  文本里面有  qwertyuiopasd
}
package com.qfedu.c_io;

import java.io.*;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        copyVideo1();
    }
    //现在咱们讲的这个是带有缓冲的,看看带有缓冲视频的复制的耗时多少 2610ms
    //写一个方法将bbb文件夹下面的3.map4格式的视频复制到aaa文件夹下面
    //用带缓冲的,效率高
    public static void copyVideo () throws IOException {
        //获取系统的当前的毫秒数
        long start = System.currentTimeMillis();
        //1.创建字节缓冲输入流  将磁盘的数据读取到内存
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("c:/bbb/3.mp4")));

        //2.创建字节缓冲输出流   从内存写入到的文件  源文件是mp4格式,写入到的也必须是mp4格式的
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("c:/aaa/goudan.mp4")));

        //3.准备一个字节数组 缓冲区数组
        byte[] buf = new byte[4 * 1024];//代码走到这一步是空的
        //4.从磁盘读取数据到内存
        int length = -1;
        //这个视频很大,依靠循环来读取,每次读4 * 1024字节
        while ((length = bis.read(buf)) != -1) {//从磁盘上读取数据到buf缓冲数组中
            //每次循环 buf数组中有值,顺便依靠循环写入到磁盘
            System.out.println("qwer");
            bos.write(buf, 0, length);

        }
        //5.关闭流
        bos.close();
        bis.close();
        //复制完以后再得到一个毫秒数,相减 就得到复制一个视频需要的时间
        long end = System.currentTimeMillis();
        System.out.println(end - start);


    }
    //下面来=看一下不带缓冲的流的读写
    public static void copyVideo1 () throws IOException {
        long start = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream(new File("c:/bbb/3.mp4"));
        FileOutputStream fos = new FileOutputStream(new File("c:/aaa/goudan.mp4"));
        int length = -1;
        while ((length = fis.read()) != -1) {
            fos.write(length);
        }
        fos.close();
        fis.close();
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

1.2.3字符输入流【非重点】

也是输入流,将磁盘的某一个文件读取到内存

FileReader:

是一个阅读字符文件的便利类,是专门处理字符文件的,比如txt文件。音频视频图片

不能使用这个流。

是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集

牵涉到解码,底层是字节流,但是会解码为字符。如果解码失败就意味着咱们读取失败了

一般不会使用字符流操作图片 音频 视频等,因为牵涉到解码。会出问题!!!

开发一般使用字节流!!!

package com.qfedu.d_FileReader;

import java.io.*;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //将c盘下面的aaa文件夹下面的1.txt文件的内容 读取到Java内存中
        //和字节流一模一样
        //1.新建一个File对象
        File file = new File("c:/aaa/1.txt");
        //2.新建FileReader  对象 字符输入流
        FileReader fr = new FileReader(file);
        //3.FileRFeader没有缓冲的效果,可以加上缓冲的效果
        //杂加?BufferedReader
        BufferedReader br = new BufferedReader(fr);
        //4.字节的缓冲数组 是字节
        //字符的缓冲数组  是字符
        char[] cbuf = new char[4];//缓冲区是4个字符
        //这个方法是用的!!!
        //5.	read(char[] cbuf) 将文件内容读取到字符数组中(缓冲区)
        int length = -1;
        
        while ((length = br.read(cbuf)) != -1) {
            System.out.println(length);
            //6.将数组展示到控制台
            System.out.println(new String(cbuf, 0, length));
        }

        //7.关闭流
        br.close();
        fr.close();

    }
}
package com.qfedu.d_FileReader;

import java.io.*;

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //将c盘下面的aaa文件夹下面的1.txt文件的内容 读取到Java内存中
        //和字节流一模一样
        //1.新建一个File对象
        File file = new File("c:/aaa/1.txt");
        //2.新建FileReader  对象 字符输入流
        FileReader fr = new FileReader(file);
        //3.FileRFeader没有缓冲的效果,可以加上缓冲的效果
        //杂加?BufferedReader
        BufferedReader br = new BufferedReader(fr);

        //这个方法不用!!!
        //5.int	read() 一次读取一个字符,返回值是字符对应的assic码值
        int length = -1;
        while ((length = br.read()) != -1) {
            System.out.println(length);

        }

        //7.关闭流
        br.close();
        fr.close();

    }
}
package com.qfedu.d_FileReader;

import java.io.*;

public class Demo3 {
    public static void main(String[] args) throws IOException {
        //将c盘下面的aaa文件夹下面的1.txt文件的内容 读取到Java内存中
        //和字节流一模一样
        //1.新建一个File对象
        File file = new File("c:/aaa/1.txt");
        //2.新建FileReader  对象 字符输入流
        FileReader fr = new FileReader(file);
        //3.FileRFeader没有缓冲的效果,可以加上缓冲的效果
        //杂加?BufferedReader
        BufferedReader br = new BufferedReader(fr);
        //4.字节的缓冲数组 是字节
        //字符的缓冲数组  是字符
        char[] cbuf = new char[4];//缓冲区是4个字符
        //这个也不用!!!
        //5.	read(char[] cbuf, 0, length) 将文件内容读取到字符数组中(缓冲区)
        int length = -1;
        while ((length = br.read(cbuf, 0, 2)) != -1) {
            System.out.println(length);
            //6.将数组展示到控制台
            System.out.println(new String(cbuf, 0, length));
        }

        //7.关闭流
        br.close();
        fr.close();

    }
}
package com.qfedu.d_FileReader;

import java.io.*;

public class Demo4 {
    public static void main(String[] args) throws IOException {
        //将c盘下面的aaa文件夹下面的1.txt文件的内容 读取到Java内存中
        //和字节流一模一样
        //1.新建一个File对象
        File file = new File("c:/aaa/1.txt");
        //2.新建FileReader  对象 字符输入流
        FileReader fr = new FileReader(file);
        //3.FileRFeader没有缓冲的效果,可以加上缓冲的效果
        //杂加?BufferedReader
        BufferedReader br = new BufferedReader(fr);
        //一次读取一行数据,r如果到达行的末尾就返回就是一个null
//        String s = br.readLine();
//        System.out.println(s);
//        String s1 = br.readLine();
//        System.out.println(s1);
        String str;
        //有可能会用的
        while ((str = br.readLine()) != null) {
            System.out.println(str);
        }


        //7.关闭流
        br.close();
        fr.close();

    }
}

1.2.4z字符输出流

案例:

将一个字符串类型的数据写入到磁盘中

FileWriter

写字符文件一个便利类

package com.qfedu.e_fileWriter;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Demo1 {
    public static void main(String[] args) throws IOException {
        //从内存写入数据到磁盘的文件中
        File file = new File("c:/aaa/2.txt");
        FileWriter fw = new FileWriter(file);
        //加缓冲流
        BufferedWriter bw = new BufferedWriter(fw);
        //viod writer(char[] cbuf, int off, int length);
        String str = "今天的天气真的太热了";
        //将字符串转为char数组
        char[] chars = str.toCharArray();
        //将chars数组中  从0 开始  取3个字符写入到缓冲流中
        bw.write(chars, 3, 3);
        bw.close();
        fw.close();


    }
}
package com.qfedu.e_fileWriter;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //从内存写入数据到磁盘的文件中
        File file = new File("c:/aaa/2.txt");
        FileWriter fw = new FileWriter(file);
        //加缓冲流
        BufferedWriter bw = new BufferedWriter(fw);
        //viod writer(char[] cbuf);
        String str = "今天的天气真的太热了";
        //将字符串转为char数组
        char[] chars = str.toCharArray();
        //将chars数组中,直接将字符数组中的所有的数据写到缓冲流中
        bw.write(chars);
        bw.close();
        fw.close();


    }
}
package com.qfedu.e_fileWriter;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Demo3 {
    public static void main(String[] args) throws IOException {
        //从内存写入数据到磁盘的文件中
        File file = new File("c:/aaa/2.txt");
        FileWriter fw = new FileWriter(file);
        //加缓冲流
        BufferedWriter bw = new BufferedWriter(fw);
        //viod writer(String str);

        String str = "对方网络不佳!!!";
        //viod writer(String str, int off, int length);
       //bw.write(str);
       //bw.write(str, 1, 4);
        bw.write("呵呵");
        bw.newLine();//写完呵呵以后换行写  功能代码 起到一个换行的作用
        bw.write("哈哈");
        bw.newLine();
        bw.write("嘻嘻");
        bw.close();
        fw.close();


    }
}

综合案例:

复制一本小说到另外一个盘符下面

package com.qfedu.e_fileWriter;

import java.io.*;

public class Demo4 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(new File("c:/bbb/DiBa.txt")));
        BufferedWriter bw = new BufferedWriter(new FileWriter(new File("c:/aaa/sb1.txt")));

        int length = -1;
        char[] cbuf = new char[4 * 1024];
        while ((length = br.read(cbuf)) != -1) {
            bw.write(cbuf, 0, length);

        }
        bw.close();
        br.close();

    }
}

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1041135.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号