一篇文章搞定Java的重要的I/O流 -小白笔记

在这里插入图片描述
本文有些内容转载自
赵彦军博客

JavaIO流结构:

在这里插入图片描述
在这里插入图片描述

什么是IO

  • 其实I/O的解释有很多,这里主要讲的I/O 是 Input/Output 的缩写, I/O 技术是非常实用的技术,List item用于处理设备之间的数据传输 。 如 读 写文件,网络通讯等。
  • Java 程序中,对于数据的输入 输出操作 以 “流 stream 的方式进行。
  • java.io 包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法 输入或输出数据

流的分类

  • 根据处理数据类型的不同分为:字符流和字节流。
  • 根据数据流向不同分为:输入流和输出流。
    在这里插入图片描述

字符流与字节流

  • 字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点.
  • 所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列.
  • 字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 2.字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。

输入流与输出流

  • 按对象分别:若将数据传到程序则为输入流,从程序输出到数据即为输出流,看上图。

四个重要基类:

  • InputStream 字节输入流
  • OutputStream 字节输出流
  • Reader 字符输入流
  • Writer 字符输出流

节点流与处理流

节点流:直接从数据源或目的地读写数据
在这里插入图片描述
常用的节点流

  • 父 类 :InputStream 、OutputStream、 Reader、 Writer

  • 文 件 :FileInputStream 、 FileOutputStrean 、FileReader 、FileWriter 文件进行处理的节点流

  • 数 组 :ByteArrayInputStream、 ByteArrayOutputStream、 CharArrayReader 、CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)

  • 字符串 :StringReader、 StringWriter 对字符串进行处理的节点流
    管 道 :PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 对管道进行处理的节点流

处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
在这里插入图片描述
常用的处理流

  • 缓冲流:BufferedInputStrean 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增加缓冲功能,避免频繁读写硬盘。
  • 转换流:InputStreamReader 、OutputStreamReader实现字节流和字符流之间的转换。
  • 数据流: DataInputStream 、DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来。

转换流

  • InputStreamReader 、OutputStreamWriter 要InputStream或OutputStream作为参数,实现从字节流到字符流的转换

在实际例子中先介绍java.io.File类

  • 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。

File类常用的构造器与方法

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

iO流实例用法

1.首先造流
2. 读入或写出
3. 关流

必须掌握:节点流的文件复制演示

字节流Demo:

	 @Test
    public void testFileInputOutputStream()  {
        //1.造流
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //用File类读入文件
            File srcFile = new File("xxx.jpg");
            File destFile = new File("xxx2.jpg");

            //将文件放入流中
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);

            //复制的过程
            byte[] buffer = new byte[5];
            int len;
            while((len = fis.read(buffer)) != -1){
                fos.write(buffer,0,len);//写出文件
            }

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

            }
        }

    }

必须掌握:使用缓冲流加速视频复制效果,这里我写成了方法:

  • 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
 //实现文件复制的方法
    public void copyFileWithBuffered(String srcPath,String destPath){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            //1.造文件
            File srcFile = new File(srcPath);
            File destFile = new File(destPath);
            //2.造流
            //2.1 造节点流
            FileInputStream fis = new FileInputStream((srcFile));
            FileOutputStream fos = new FileOutputStream(destFile);
            //2.2 造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3.复制的细节:读取、写入
            byte[] buffer = new byte[1024];
            int len;
            while((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源关闭
            if(bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

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

            }
    @Test
    public void testCopyFileWithBuffered(){
        long start = System.currentTimeMillis();

        String srcPath = "C:\\Users\\Administrator\\Desktop\\01-视频.avi";
        String destPath = "C:\\Users\\Administrator\\Desktop\\03-视频.avi";


        copyFileWithBuffered(srcPath,destPath);


        long end = System.currentTimeMillis();

        System.out.println("复制操作花费的时间为:" + (end - start));//618 - 176
    }
            

必须掌握:转换流演示实现字节流转向字符流:

将UTF-8格式转换为gbk格式

  @Test
    public void test2() {
        InputStreamReader isr = null;
        OutputStreamWriter osw = null;
        try {
            //1.造文件、造流
            File file1 = new File("dbcp.txt");
            File file2 = new File("dbcp_gbk.txt");
			//造字节流
            FileInputStream fis = new FileInputStream(file1);
            FileOutputStream fos = new FileOutputStream(file2);

            isr = new InputStreamReader(fis, "utf-8");
            osw = new OutputStreamWriter(fos, "gbk");

            //2.读写过程
            char[] cbuf = new char[20];
            int len;
            while ((len = isr.read(cbuf)) != -1) {
                osw.write(cbuf, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //3.关闭资源
            if (isr != null) {

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

必须掌握:对象流演示,序列化时注明序列号!

  • 作用:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。

序列化机制:

  • 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种
  • 二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。
  • 当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。
//序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
  //  使用ObjectOutputStream实现
 @Test
    public void testObjectOutputStream(){
        ObjectOutputStream oos = null;

        try {
            //1.
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            //2.
            oos.writeObject(new String("我爱中国"));
            oos.flush();//刷新操作

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

    }
    /*
    反序列化:将磁盘文件中的对象还原为内存中的一个java对象
    使用ObjectInputStream来实现
     */
    @Test
    public void testObjectInputStream(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.dat"));

            Object obj = ois.readObject();
            String str = (String) obj;
            System.out.println(str);//我爱中国

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

            }
        }
    }

最后:

知识是分享的,小白想与大家学习,若文章不好,请大佬指点!
喜欢我的话可以关注公众号:小白编码。

本文有些内容有些转载于:赵彦军
在这里插入图片描述

发布了12 篇原创文章 · 获赞 39 · 访问量 647

猜你喜欢

转载自blog.csdn.net/weixin_46146269/article/details/104919169