Jave中IO的详细总结

前语

如果你仅仅就是想读取以及存文本文件和图片之类的文件,可以直接看字节流的两个案例或者效率更高的缓冲字节流。
如果仅仅想要对文本文件进行读写,可以看最常用的复制文件的方式。

IO流概述和分类

IO流介绍

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

IO流的分类

  • 按照数据的流向:
    • 输入流:读数据
    • 输出流:写数据
  • 按照数据类型来分
    • 字节流
      • 字节输入流
      • 字节输出流
    • 字符流
      • 字符输入流
      • 字符输出流

IO流的使用场景

  • 如果操作的是纯文本文件,优先使用字符流
  • 如果操作的是图片、视频、音频等二进制文件。优先使用字节流
  • 如果不确定文件类型,优先使用字节流。字节流是万能的流

File文件是干嘛的

File文件就是在程序中设置的一个可以表示具体文件的一个对象,你仅仅File file = new File(—)是不会产生真实对象的,就是一种表示方式。

package file_test;


import java.io.File;
//import java.io.FileReader;
import java.io.IOException;

public class FileDemo02 {
    public static void main(String[] args) throws IOException {
        File f1 = new File("C:\\Users\\45512\\Desktop\\java试验文件\\java.txt");
        System.out.println(f1.createNewFile());
        System.out.println("-------------");

        File f2 = new File("C:\\Users\\45512\\Desktop\\java试验文件\\JavaSE");
        System.out.println(f2.mkdir());
        System.out.println("----------");

        File f3 = new File("C:\\Users\\45512\\Desktop\\java试验文件\\JavaWEB\\HTNL");
        System.out.println(f3.mkdirs());
        System.out.println("-------");

        File f4 = new File("C:\\Users\\45512\\Desktop\\java试验文件\\javase.txt");
        System.out.println(f4.createNewFile());

    }


}

字节流

网上关于文字的述说有许多,个人感觉只有概念没有实例是无法领会知识的真正含义的,在这里我将以代码的形式向大家展现:

字节流的写入

package file_test;

/*
字节流写入数据分3步:
    1.创建字节输出流对象
    2.调用write方法写入数据
    3.释放资源
*/
//import java.io.FileNotFoundException;

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

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

        FileOutputStream fos = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        /*
        做了3件事:
        1.调用系统创建了文件
        2.创建了字节输出流对象
        3.让字节输出流对象指向创建好的文件
        */
        fos.write(97);//被转化成了a

        fos.write(57);
        fos.write(55);//这两个可以凑97

        fos.close();
        /*
        做了2件事:
        1.关闭此文件输出流
        2.释放此流相关联得任何系统资源
        */


    }
}

txt文件:
这是txt文件
字节流三种不同的写入方式:

package file_test;

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

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

        File file = new File("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        FileOutputStream fos = new FileOutputStream(file);
        //下面的和上面的相同
        //FileOutputStream fos = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        //FileOutputStream fos = new FileOutputStream("new File(C:\\Users\\45512\\CAJ_wenjian\\fos.txt)");

        fos.write(97);
        fos.write(98);
        fos.write(99);
        fos.write(100);
        fos.write(101);

        byte[] bys = {97,98,99,100,101};
        fos.write(bys);
        //getBytes():返回字符串对应的字节数组
        //\r\n在windows操作系统中是换行的意思
        fos.write("\r\nabcde".getBytes());

        fos.write(bys,0,bys.length);//从第0位起后length长度
        fos.write(bys,1,3);

        //如何写追加写入的文件————在创建文件的时候解决,后面加一个
        FileOutputStream fos2 = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\fos1.txt",true);
        for (int i=0;i<5;i++){
            fos2.write("helloWorld".getBytes());
            fos2.write("\r\n".getBytes());
        }


        fos.close();
    }
}

运行一次后txt的文件:
在这里插入图片描述

在这里插入图片描述
运行两次后txt的文件:
在这里插入图片描述

在这里插入图片描述
上面都是用throws抛出异常,那么,如果不要抛出异常,要解决异常又该怎么写呢?

package file_test;

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

public class FileOutputStreamDemo03 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        //这里如果=null不写则会报错,因为fos没有进行初始化
        try {
            fos = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
            fos.write("hello".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

为什么要将close写到finally里面呢?大家不妨思考一下。

如果将其放在try里面,当文件路径不存在时,系统资源就无法释放。那为什么要在finally里面套上if语句哩?这是为了增强程序的健壮性,如果文件不存在,则fos是null,null.close(),就会报空指针异常。

字节流的读入

先给上需要读入的txt文件:
在这里插入图片描述
再给上代码,一切便清晰了。

package file_test;

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

/*
字节流写入数据分3步:
    1.创建字节输入流对象
    2.调用read()方法//如果文件到达末尾,返回值就是-1
    3.释放资源
*/
public class FileInputStreamDemo01 {
    public static void main(String[] args) throws IOException {

        FileInputStream fis = new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        FileInputStream fis2 = new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        /*
        //第一次读取数据
        int by = fis.read();
        System.out.println(by);//97
        System.out.println((char)by);//a

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

        int by = fis.read();
        while (by!=-1){
            System.out.print((char)by);
            by = fis.read();//如果不进行读取,则始终读取第一位数
        }
        System.out.println("\n--------");


        //优化上面的代码,标准读入代码
        int by1;
        while ((by1=fis2.read())!=-1){
            System.out.print((char)by1);
        }

        fis.close();
        fis2.close();

    }
}

在这里插入图片描述
下面是字节流读数据到控制台操作,首先给上txt文件:
在这里插入图片描述

package file_test;

import java.io.*;

public class FileInputStreamDemo02{
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        byte[] bys = new byte[5];

        //第一次读取数据
        int len = fis.read(bys);//len指读取的字节的长度
        System.out.println(len);
        System.out.println(new String(bys,0,len));

        //第二次读取数据
        len = fis.read(bys);
        System.out.println(len);
        System.out.println(new String(bys,0,len));

        //第三次读取数据
        len = fis.read(bys);
        System.out.println(len);
        System.out.println(new String(bys,0,len));
        /*
        注意记事本world后要按一个Enter键
        hello\r\n
        world\r\n
        下面是System.out.println(new String(bys));的结果
        第一次读取数据时:h e l l o
        第一次读取数据时:\r \n w o r
        第三次读取数据时:l d \r \n r(r没有替换保留)
         */
        fis.close();
    }
}

在这里插入图片描述
下面是将 System.out.print(new String(bys))改成System.out.println(new String(bys,0,len));的结果
在这里插入图片描述
当然最实用的是下面的循环代码

package file_test;

import java.io.*;

public class FileInputStreamDemo02{
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        
        byte[] bys = new byte[1024];//1024的整数倍
        int len;
        while((len=fis.read(bys))!=-1){
            System.out.print(new String(bys,0,len));
        }
        
        fis.close();
    }
}

在这里插入图片描述

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

把一个txt文件里面的内容复制到另一个txt文件中。
原文件:
在这里插入图片描述

package file_test;

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

public class CopyTxtDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        FileOutputStream fos = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\fos1.txt");
        int x;
        while ((x=fis.read())!=-1){
            fos.write(x);
        }
        fis.close();
        fos.close();
    }

复制后得到的fos1.txt文件
在这里插入图片描述

字节流案例:复制图片文件

package file_test;

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

public class CopyTxtDemo {
    public static void main(String[] args) throws IOException {
        /*FileInputStream fis = new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\fos.txt");
        FileOutputStream fos = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\fos1.txt");
        int x;
        while ((x=fis.read())!=-1){
            fos.write(x);
            System.out.println(x);
        }
        fis.close();
        fos.close();*/
        FileInputStream fis = new FileInputStream("C:\\Users\\45512\\Desktop\\java学习资料\\素材\\itcast\\mn.jpg");
        FileOutputStream fos = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\mn.jpg");
        byte[] bys = new byte[1024];
        int len;
        while((len=fis.read(bys))!=-1){
            fos.write(bys);
        }
        fos.close();
        fis.close();
    }
}

字节缓冲流介绍

  1. BufferOutputStream:该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
  2. BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
  3. 简而言之,字节缓冲流可以提高效率,需要注意的是,字节缓冲流仅仅提供缓冲区,而真正的读写还得依靠基本的字节流对象进行操作。
package file_test;

import java.io.*;
//import java.io.FileNotFoundException;


public class BufferStreamDemo {
    public static void main(String[] args) throws IOException {
        /*FileOutputStream fos = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\bos.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);*/
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\bos.txt"));
        bos.write("hello\r\n".getBytes());
        bos.write("world\r\n".getBytes());
        bos.close();

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\bos.txt"));

        /*
        读数据的第一种方式
        int by;
        while ((by=bis.read())!=-1){
            System.out.print((char)by);
        }*/
        //读数据的第二种方式
        byte[] bys = new byte[1024];
        int len;
        while((len=bis.read(bys))!=-1){
            System.out.print(new String(bys,0,len));
        }

        bis.close();
    }
}

在这里插入图片描述

字符流

为什么会出现字符流

  1. 字符流的介绍
    由于字节流操作中文不是特别的方便,所以Java就提供字符流
    字符流 = 字节流 + 编码表
  2. 中文的字节存储方式
    用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数(UTF-8一个汉字对应3个字节,GBK一个汉字对应2个字节)

字符串和字符流中的编码解码问题

package file_test;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class StringDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "中国";

        //编码
        //byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
        byte[] bys = s.getBytes();//默认用UTF-8编码,结果:[-28, -72, -83, -27, -101, -67]
        //byte[] bys = s.getBytes("GBK");//指定编码为GBK(需要抛出异常),结果:[-42, -48, -71, -6]
        System.out.println(Arrays.toString(bys));

        //解码
        String ss = new String(bys);//使用平台的默认字符集解码,结果:中国
        //String ss = new String(bys,"GBK");//使用指定的默认字符集解码,结果:涓浗
        System.out.println(ss);
    }
}
package file_test;

import java.io.*;

public class ConversionStreamDemo {
    public static void main(String[] args) throws IOException {
//        FileOutputStream fos = new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\osw.txt");
//        OutputStreamWriter osw = new OutputStreamWriter(fos);
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\osw.txt"));
        //下面这个就是以指定的编码方式进行编码
//      OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\osw.txt"),"UTF-8");
        osw.write("中国");
        osw.close();


        InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\osw.txt"));
        //一次读取一个字符数据
        int ch;
        while ((ch=isr.read())!=-1){
            System.out.print((char)ch);
        }

        isr.close();

    }
}

字符流写文件的5种方式

在这里插入图片描述
其中第4种用得最多。

package file_test;

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

public class OutputStreamWriteDemo {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\Users\\45512\\CAJ_wenjian\\osw.txt"));
        //void write(int c)
        osw.write(97);
        osw.flush();//刷新流,不刷新文本不显示
        osw.write(98);

        osw.write("\r\n");

        //void write(char[] cbuf)
        char[] chs = {'a','b','c','d','e'};
        osw.write(chs);

        osw.write("\r\n");
        //void write(char[] cbuf,int off,int len)
        char[] chs1 = {'a','b','c','d','e'};
        osw.write(chs1,0,chs.length);

        osw.write("\r\n");
        //void write(String str);
        osw.write("abdbhjd");

        osw.write("\r\n");
        //void write(String str,int off,int len);
        osw.write("abhdjc",1,3);

        osw.close();//调用close会自动刷新
    }
}

在这里插入图片描述

字符流读数据的两种方式

在这里插入图片描述

package file_test;

import java.io.*;

public class InputStreamReaderDemo  {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\osw.txt"));
        InputStreamReader isr1 = new InputStreamReader(new FileInputStream("C:\\Users\\45512\\CAJ_wenjian\\osw.txt"));

        //int read():一次读取一个数据
        int ch;
        while ((ch=isr.read())!=-1){
            System.out.print((char)ch);
        }

        System.out.println();
        //int read(char[] cbuf):读字符串数组
        char[] chs = new char[1024];
        int len;
        while((len=isr1.read(chs))!=-1){
            System.out.println(new String(chs,0,len));
        }

        isr.close();
    }
}

在这里插入图片描述

字符流的便捷类——FileReader和FileWriter

FileReader是OutputStreamReader的子类,用法和它差不多,但是不可以做流的编码,同理,FileWriter是OutputStreamWriter的子类。
这里就通过一个案例来进行了解吧——复制java文件。

package file_test;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyJavaDemo02 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("C:\\Users\\45512\\CAJ_wenjian\\Demo\\src\\file_test\\ConversionStreamDemo.java");
        FileWriter fw = new FileWriter("C:\\Users\\45512\\CAJ_wenjian\\Demo\\src\\file_test\\Copy.java");

/*        int ch;
        while ((ch=fr.read())!=-1){
            fw.write(ch);
        }*/

        char[] chs = new char[1024];
        int len;
        while((len=fr.read(chs))!=-1){
            fw.write(chs,0,len);
        }

        fw.close();
        fr.close();
    }
}

缓冲字符流

这个是为了提高读写效率的。
和字节缓冲流也十分相似。

package file_test;

import java.io.*;

public class BufferedStreamDEmo01  {
    public static void main(String[] args) throws IOException{
        BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\45512\\CAJ_wenjian\\bw.txt"));
        bw.write("hello\r\n");
        bw.write("world\r\n");
        bw.close();

        BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\45512\\CAJ_wenjian\\bw.txt"));
        int ch;
        while((ch=br.read())!=-1){
            System.out.print((char)ch);
        }
        /*
        char[] chs = new char[1024];
        int len;
        while((len=br.read(chs))!=-1){
            System.out.println(new String(chs,0,len));
        }*/
        br.close();
    }
}

在这里插入图片描述
字节缓冲流有什么特有更能呢?下面我们来看一下:

  1. BufferdWriter():
    void newLine():写一行行分隔符,行分隔符字符串由系统属性定义。
  2. Buffer额度Reader:
    public String readline():读一行文字。结果包含行的内容的字符串,不包括任何终止字符(即不包括换行符),如果流的结尾已经到达,则为null。
package file_test;

import java.io.*;

public class BufferedStreamDemo02 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\45512\\CAJ_wenjian\\bw.txt"));
        for (int i = 0; i < 10; i++) {
            bw.write("hello" + i);
            //bw.write("\r\n");这个方法只适合windows系统,不太好
            bw.newLine();
            bw.flush();
            //该方法写入数据这三条语句都要写
        }
        bw.close();

        BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\45512\\CAJ_wenjian\\bw.txt"));
        String line;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
        br.close();
    }
}

在这里插入图片描述

最常用的复制文件的方式

package file_test;

import java.io.*;

public class CopyJavaDemo03 {
    public static void main(String[] args) throws IOException {
        BufferedReader br= new BufferedReader(new FileReader("C:\\Users\\45512\\CAJ_wenjian\\Demo\\src\\file_test\\ConversionStreamDemo.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\45512\\CAJ_wenjian\\Demo\\src\\file_test\\Copy.java"));

        String line;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

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

IO小结

在这里插入图片描述
在这里插入图片描述
至此,IO的大部分知识结束了,你掌握了吗?
如果对你有帮助的话,不妨点个赞呗!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值