IO流

IO流:输入输出流。在java中,IO流用来进行设备之间的设备数据传输(上传,下载都是用到IO流完成),数据在电脑中是以文件的形式存在。所以我们需要在学习IO流之前,学习两个准备知识。

在java中,对于遇到的问题,有一个类来描述(Throwable类)。Throwable 类是 Java 语言中所有错误或异常的父类。两个子类的实例,ErrorException,通常用于指示发生了异常情况

Exception:异常,描述一般性的问题,它指出了合理的应用程序想要捕获的条件。异常分为两种情况:编译期异常(非RuntimeException及其子类)和运行期异常(RuntimeException及其子类)。编译其异常必须解决,否则程序无法执行。运行期非必需解决。

Error:错误,严重的问题,用于指示合理的应用程序不应该试图捕获的严重问题,既我们无法解决,比如内存溢出等。

运行期异常

当遇到异常时,没有处理异常,java使用默认处理方式,java在遇到异常时会打印异常堆栈信息然后推出虚拟机,不再打印后面的内容,我们可以自己处理运行期异常,使用try catch.

try{}的大括号里面的方式的有可能出现问题的代码,catch()的小括号里面为:一旦出现异常,我们的处理逻辑

 int a = 10;
        int b = 0;
      
        try{
            System.out.println(a / 0);
        }catch (ArithmeticException e){
            System.out.println("除数为0了");
        }

        System.out.println("后面代码");
        System.out.println("后面代码");
        System.out.println("后面代码");
        System.out.println("后面代码");
        System.out.println("后面代码");
        System.out.println("后面代码");

多个等可能的异常出现时

 int[] arr = {20, 30};
        int a = 10;
        int b = 0;
        //ArrayIndexOutOfBoundsException
        //ArithmeticException
        try {
            arr = null;
            System.out.println(arr[0]);
            System.out.println(a / b);
            System.out.println(arr[3]);
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界异常");
        }catch (ArithmeticException e){
            System.out.println("除数为0了");
        }catch (NullPointerException e){
            System.out.println("空指针异常");
        } catch (Exception e) {
            System.out.println("其他异常");
        }

注意,能明确的异常尽量明确,不要拿最大的Exception异常一步了之,因为发生异常时我们不知道具体发生了什么相应的异常。捕获的多个异常中,有父子继承关系,父类异常放到最后。try{}的大括号里面的方式的有可能出现问题的代码,没有问题的代码不要放,浪费性能。

jDK1.7之后提供了一种捕获多种异常的语法

  //JDK1.7之后提供了一种捕获多种异常的语法
        int[] arr = {20, 30};
        int a = 10;
        int b = 0;
        //ArrayIndexOutOfBoundsException
        //ArithmeticException
        try {
            //arr = null;
            System.out.println(a / b);
            System.out.println(arr[0]);

            System.out.println(arr[3]);
            
        } catch (ArrayIndexOutOfBoundsException | NullPointerException | ArithmeticException e) {
            if (e instanceof ArrayIndexOutOfBoundsException) {
                System.out.println("索引越界异常");
            } else if (e instanceof NullPointerException) {
                System.out.println("空指针异常");
            } else if (e instanceof ArithmeticException) {
                System.out.println("数学异常");
            }

finally最终的: 不管try里面的代码有没有遇到异常,那么finally里面的代码都会执行。一般我们会在finally善后收尾的的代码写finally里面 比如释放资源

 int a=10;
        int b=0;
        try{
            //ctrl+shift+上下方向键,可以上下挪动一样代码
            System.out.println(a / 0);
        }catch (ArithmeticException e){
            System.out.println("除数为0了");
        }finally {
           
            System.out.println("不管try里面的代码有没有遇到异常,那么finally里面的代码都会执行");
        }


 Scanner scanner = null;
        try {
            //System.out.println(1/0);
            scanner = new Scanner(System.in);
            System.out.println("请输入第一个整数");
            int one = scanner.nextInt();
            System.out.println("请输入第二个整数");
            int two = scanner.nextInt();
            System.out.println(one / two);
        } catch (ArithmeticException e) {
            System.out.println("除数为0");
        } finally {
            //释放资源
            System.out.println("释放资源");
            if (scanner != null) {
                scanner.close();
            }
        }

        System.out.println("下面的代码");
    }

编译期异常

编译器异常有两种处理方式

方式一:使用throw向上抛出,给调用者处理,谁调用谁处理。

public static void main(String[] args) throws ParseException {
       
        String dateStr="2020-=02-23";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
      
        Date date= simpleDateFormat.parse(dateStr);
        System.out.println(date);
        
        System.out.println("下面 代码");
    }
}

方式二:使用try catch 捕获处理

 public static void main(String[] args) {
        
        String dateStr = "2020-02-23";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
      
        try {
            Date date = simpleDateFormat.parse(dateStr);
            System.out.println(date);
        }catch (ParseException e){
            System.out.println("解析失败");
        }
        System.out.println("下面代码");
    }
}

一般来说,抛到main方法里面就不再抛出了,而是自己捕获处理,这种方式比较友好一些

工具类里面的异常,你就抛出去,抛给调用工具类的人他去处理

  public static Date parseDateStr(String dateStr, String formate) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
       

        Date date = simpleDateFormat.parse(dateStr);
        return date;

用异常处理进行键盘录入操作

 public static void main(String[] args) {
       
        while (true) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入一个整数");
            try {
                int num = sc.nextInt();
                System.out.println(num);
                break;
            } catch (InputMismatchException e) {
                System.out.println("输入类型不正确,请重新输入");
            }

        }
    }
}

throws 和 throw的区别

    //相同点是都可以进行异常的抛出
    //throws用在方法声明上
    //throw使用用在方法内部抛出异常

   /* 
    throws和throw的区别
    a:throws
    用在方法声明后面,跟的是异常类名
    可以跟多个异常类名,用逗号隔开
    表示抛出异常,由该方法的调用者来处理
    throws表示出现异常的一种可能性,并不一定会发生这些异常
    b:
    throw
            用在方法体内,跟的是异常对象名
            只能抛出一个异常对象名
    这个异常对象可以是编译期异常对象, 可以是运行期异常对象
    表示抛出异常,由方法体内的语句处理
    throw则是抛出了异常对象,
    执行throw则一定抛出了某种异常*/

自定义异常

在我们开发项目中,会遇到各种各样的异常,那么Java给我们提供的这些异常类,并不能完全描述我们所遇到的各种异常。如扫码异常等。

   Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的取款金额"); 
        double num = scanner.nextDouble();
        quKuan(num);

    }

    private static void quKuan(double num) {
        if(num<=money){
            money -= num;
            System.out.println("取款成功");
        }else{
           // System.out.println("余额不足");
            //余额不足,就要抛出异常,程序终止。
            throw new NoMoneyException("余额不足");

1.子类在重写父类方法时,如果父类方法,没有抛出异常,子类不能抛出异常

2.子类在重写父类方法时,子类不能抛出父类没有抛出过的异常。

3.子类在重写父类方法时,子类抛出的异常,可以比父类小,或者与父类相同

4.子类在重写父类方法时,父类抛出异常时,子类不可以抛出异常

快捷捕获异常ctrl+alt+t或者在程序之后:如System.out.printin(1/0).try,即可

File类的概述

java为了描述电脑文件、目录等,提供了File类

File(File parent, String child)

​ 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

 File file = new File("C:\\Users\\ShenMouMou\\Desktop\\aaa.txt");
File(String pathname) 

通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。

 File fuPath = new File("C:\\Users\\ShenMouMou\\Desktop");
File(String parent, String child) 

根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。

 File file2 = new File("C:\\Users\\ShenMouMou\\Desktop", "aaa.txt");

绝对路径与相对路径

绝对路径:带有盘符的地址值:如E:\steam\Steam.exe

相对路径:不带有盘符号的路径:如文件夹里面有子文件

//绝对路径
 File file1 = new File("E:\\IdeaProjects\\20200523-File-类-下午\\a.txt");
        System.out.println(file1);

        File file2 = new File("E:\\IdeaProjects\\20200523-File-类-下午\\b.txt");
        System.out.println(file2);
//相对路径
 File file3 = new File("a.txt");
        System.out.println(file3);

        File file4 = new File("b.txt");
        System.out.println(file4);

用的相对路径 ./ 当前路径 指的是项目文件夹的根目录下

用的相对路径 …/ 表示上一级路径

…/…/ 当前目录的上两级目录

成员方法:

创建文件。

//使用绝对路径,在桌面上创建一个文件夹
        File file2 = new File("C:\\Users\\ShenMouMou\\Desktop","demo");
        boolean mkdir = file2.mkdir();
        System.out.println(mkdir);
        //mkdir() 这个方法的不好之处,就是只能创建单级文件夹

        //如果要创建多级文件夹,我们可以使用另外一个方法

        File file3 = new File("C:\\Users\\ShenMouMou\\Desktop", "aaa/bbb/ccc");
       // mkdirs(); 可以创建多级或单级文件夹。
       // boolean mkdir1 = file3.mkdir();
        boolean mkdirs = file3.mkdirs();
        System.out.println(mkdirs);

删除文件

//删除文件或文件夹
        File file = new File("a.txt");
        //删除文件,删除成功返回true,重复删除返回false
        boolean b = file.delete();
        System.out.println(b);

        File file1 = new File("img");
        file1.delete();
    }

delete() 删除文件夹的时候,只能删除空文件夹,如果是非空目录,则删除失败。

当调用delete() 方法时,直接删除文件,不管该文件是否存在,一经调用立即执行;

作业:删除非空目录,怎么删除?可以使用递归

  File file = new File("C:\\Users\\ShenMouMou\\Desktop\\demo");
        //因为demo 不是个空文件夹,所以直接删除不了。我们可以把里面的子文件全部删掉,再回过头来删这个空文件夹
        File[] files = file.listFiles();
        for (File f : files) {
            f.delete();
        }
       
        boolean b = file.delete();
        System.out.println(b);

重命名文件

 File file = new File("aaa.txt");
        File mbFile = new File("bbb.txt");
        //重命名:源文件和传入进来的这个文件对象,都在相同路径下他就是重命名
        boolean b = file.renameTo(mbFile);
        System.out.println(b);
        System.out.println("======================================");
        //renameTo(mbFile)方法 :源文件和传入进来的这个文件,不在同一路径下,就是剪贴并重命名
        File file1 = new File("eee.txt");
        File file2 = new File("C:\\Users\\ShenMouMou\\Desktop\\fff.txt");
        boolean b1 = file1.renameTo(file2);
        System.out.println(b1);

判断类功能

  //判断是不是个文件
        File file = new File("bbb.txt");
        boolean file1 = file.isFile();
        System.out.println(file1);
        //判断是不是目录
        File file2 = new File("out");
        boolean directory = file2.isDirectory();
        System.out.println(directory);

        System.out.println("================================");
        File file3 = new File("bbb.txt");
        //判断文件或文件夹是否存在
        boolean exists = file3.exists();
        System.out.println(exists);
        //判断文件是否可读
        File file = new File("C:\\Users\\ShenMouMou\\Desktop\\test.txt");
        boolean b = file.canRead();
        System.out.println(b);

        //判断文件是否可写
        boolean b1 = file.canWrite();
        System.out.println(b1);

        //判断文件是否隐藏
        boolean hidden = file.isHidden();
        System.out.println(hidden);
        //判断文件是否使用的是绝对路径
        boolean absolute = file.isAbsolute();
        System.out.println(absolute);

        File file1 = new File("bbb.txt");
        boolean absolute1 = file1.isAbsolute();
        System.out.println(absolute1);

获取类功能:

获取文件路径:

 File file = new File("a.txt");
       
        //获取文件的绝对路径,返回的是字符串类型
        String absolutePath = file.getAbsolutePath();
        System.out.println(absolutePath);
        System.out.println("==============================");
        //获取文件的绝对路径,返回的是File 这个方法比较灵活
        File absoluteFile = file.getAbsoluteFile();
        System.out.println(absoluteFile.toString());
        absoluteFile.delete();
         File file = new File("E:\\IdeaProjects\\20200524-File-类-上午", "a.txt");
        //获取文件的父路径,返回的是字符串类型
        String parent = file.getParent();
        System.out.println(parent);
        System.out.println("==========================");
        ///获取文件的父路径,返回的是File类型 这个方法灵活
        File parentFile = file.getParentFile();
        System.out.println(parentFile.toString());
       // File file1 = new File(parentFile, "b.txt");

        System.out.println("=========================================");
        File file3 = new File("E:\\IdeaProjects\\20200524-File-类-上午\\a.txt");
        //获取文件的父路径
        String parent1 = file3.getParent();
        System.out.println(parent1);
        File parentFile1 = file3.getParentFile();
        System.out.println(parentFile1);
        System.out.println("======================");
        //在封装文件时,没有指定父路径,返回就是null
        File file1 = new File("a.txt");
        String parent2 = file1.getParent();
        System.out.println(parent2);

获取磁盘容量类

 //获取磁盘的总容量,返回的是字节
        File file = new File("D://");
        long totalSpace = file.getTotalSpace();
        System.out.println((totalSpace/1024/1024/1024.0)+"GB");

        //获取磁盘的剩余容量
        long freeSpace = file.getFreeSpace();
        System.out.println((freeSpace / 1024 / 1024 / 1024.0) + "GB");

文件类获取

 File file = new File("a.txt");
        //获取文件名
        String name = file.getName();
        System.out.println(name);
        //获取文件大小
        long length = file.length();
        System.out.println(length);

public String[] list ():获取指定目录下的所有文件或者文件夹的名称数组

 File file = new File("C:\\Users\\ShenMouMou\\Desktop\\demo");

        String[] arr = file.list();
        for (String s : arr) {
            if(s.equals("2005691.jpg")){
                System.out.println("进来了");
                System.out.println(s);
               File file1 = new File(file, s);
                System.out.println(file1);
                file1.delete();

public File[] listFiles ():获取指定目录下的所有文件或者文件夹的File数组

  File file = new File("C:\\Users\\ShenMouMou\\Desktop\\demo");

        File[] files = file.listFiles();
        for (File f : files) {
            System.out.println(f.getName());
            if (f.isDirectory()) {
                f.delete();

作业:删除多级文件夹:文件夹里面套有跟多子文件夹。递归删除可以做到

package IO.delete;

import java.io.File;

public class Delete_Folder {
    public static void main(String[] args) {
        File srcFile = new File("H:\\daywork\\delete");
        deleteFolder(srcFile);
    }
 
    public static void deleteFolder(File file){
        
        if(file.isFile()){
            System.out.println("删除"+file.getName());
            file.delete();
            //不是文件的话,就是文件夹
        }else{
            //获取文件夹中的所有File对象,如果为空,则files.length为0,次处程序不执行
            File[] files=file.listFiles();
            for (int i = 0; i < files.length; i++) {
                //如果不为空,则显示显示删除的文件名称,继续调用递归
                System.out.println("删除"+files[i].getName());
                deleteFolder(files[i]);
            }
        }
        //最后删除空文件夹!!!
        file.delete();
    }
}

IO流

我们站在内存的角度看待输入输出流。

输入流:用来读取数据

输出流:用来写出数据

我们根据文件的数据类型,可以把流划分为字节流,和字符流。字节流可以操作任意类型的文件,字符流只能操作文本文件。

字节流

字节流的继承关系:

字节输入流inputStram和字节输出流outputStram。

inputStram:抽象类,是所有字节输入流的父类。常用的子类有:

outputStram:抽象类,是所有字节输出流的父类。常用子类有:

文件输出流FileOutputStram

FileOutputStram(File file)

创建一个向指定File对象表示文件中写入数据的文件输出流。

FileOutputStram(String name)

创建一个具有指定名称的文件中写入数据的输出文件流。

  File file = new File("a.txt");
        
        
        FileOutputStream out = new FileOutputStream(file);

创建文件输出流,来关联文件,当关联的文件不存在时,会自动创建这个文件。

文件中写入数据

方法有:out.write(byte[] b):输出字节数组

out.write(byte[] b, int off(选取的起始位置), int len(要写几个字节)):自顶范围输出子类数组

out.write(int b):输出单个子类

 //一次写入一个字节
        out.write(97);
        out.write(98);
        out.write(99);
        out.write(100);
//一次可以写入一个字节数组
        byte[] bytes = {101, 102, 103, 104};
        out.write(bytes);
//写入中文
        String str="爱生活";
        byte[] bytes1 = str.getBytes();
        out.write(bytes1);
        out.close();
        //最后一定要释放资源

FileOutputStram(File file, boolean append);同下,参数一,文件名,参数二,是否要追加写入数据。true/false

创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

FileOutputStram(String name, boolean append);同上

创建一个向具有指定 name 的文件中写入数据的输出文件流。

    FileOutputStream out = new FileOutputStream("c.txt",true);
   out.write("康师傅".getBytes());
    //写入换行符

  /*  windows下的换行符只用是 \r\n
    Linux \n
    Mac	\r
    */
    out.write("\r\n".getBytes());
    out.write("统一".getBytes());
    out.write("\r\n".getBytes());
    out.close();

FileOutputStram写出数据的异常处理

   FileOutputStream out=null;
        try{
            out = new FileOutputStream("c.txt");
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if (out != null) {
                    out.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }

文件输入流FileinputStram

FileInputStream(File file)

通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。

FileInputStream(String name)

通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

输入流所关联的文件,如果不存在,会报错,不会自动补充。

in.read()

从此输入流中读取一个数据字节。

 FileInputStream in= new FileInputStream("a.txt");

        //输入输入流,读取文件中的数据
        //一次读取一个字节
        int by = in.read();
        System.out.println(by);
        by = in.read();
        System.out.println(by);
        by = in.read();
        System.out.println(by);
        by = in.read();
        System.out.println(by);
        //如果读取不到有效的字节,就会返回-1 ,我们经常使用-1来判断这个文件的数据是否读取完毕。
        by = in.read();
        System.out.println(by);

        //流使用完毕,记得释放资源
        in.close();

in.read(byte[] b)

从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。

 byte[] bytes = new byte[1024];
        //把读取到的字节,装进你传进来的这个容器
        int len = in.read(bytes); //返回的是你一次实际读取到的有效字节个数
        System.out.println("读取到的有效字节个数:"+len);


        System.out.println(Arrays.toString(bytes));


        //把字节数组转换成字符串
        String s = new String(bytes, 2, len);
        System.out.println(s);

        in.close();

in.read(byte[] b, int off, int len)

从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。

 int len = in.read(bytes,0,3);

        System.out.println("读取到的有效字节个数:" + len);
        len = in.read(bytes, 0, 3);

        System.out.println("读取到的有效字节个数:" + len);
        len = in.read(bytes, 0, 3);

        System.out.println("读取到的有效字节个数:" + len);

        System.out.println(Arrays.toString(bytes));


        in.close();
    }

文件的复制

//进行文件的复制
        //方式1:读取一个字节,写入一个字节来复制文本文件
        FileInputStream in = new FileInputStream("MyTest.java");
 FileOutputStream out=new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\MyTest.java");
        int by = 0;
        while ((by = in.read()) != -1) {//只要读取还有发现-1即结束,会一直进行读写
            out.write(by);
            out.flush();
        }
        //释放资源
        in.close();
        out.close();
    }
}
实例为:
 public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream("C:\\Users\\LCH\\Desktop\\新建文件夹 (2)");
        FileOutputStream out = new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\test");
        
        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();
    }
}

但是上述方法比较慢,我们可以用一下方法

 FileInputStream in = new FileInputStream("MyTest.java");
        FileOutputStream out = new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\MyTest123.java");
        //定义一个字节数组,来充当缓冲区
        byte[] bytes = new byte[1024 * 8];
        //定义一个变量,来记录每次读取到的有效字节个数
        int len=0;
        //频繁的读写

        while ((len=in.read(bytes))!=-1){
            out.write(bytes,0,len);
            out.flush();
        }
        //释放资源
        in.close();
        out.close();
    }
}

流的异常处理(抓取 处理)

 FileInputStream in = null;
        FileOutputStream out = null;
        try {
            //System.out.println(1 / 0);如果此处发生异常,无法进行以下代码,既用到以下格式
            in = new FileInputStream("E:\\课堂录制视频\\录像160.mp4");
            out = new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\test.mp4");
            byte[] bytes = new byte[1024 * 8];
            int len = 0;
            long start = System.currentTimeMillis();
            while ((len = in.read(bytes)) != -1) {
           
                out.write(bytes, 0, len);
                out.flush();
            }
            long end = System.currentTimeMillis();
            System.out.println("复制完成共耗时" + (end - start) + "毫秒");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

高效的字节输入输出流

BufferdInputStream:输入

创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。

BufferdOutputStream:输出

创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

 private static void test4() throws IOException{
        BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\ShenMouMou\\Music\\音乐\\音乐\\塞任唱片-MSR - Renegade.mp3"));
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\塞任唱片-MSR - Renegade.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();
    }

字符流

在学习字符流之前,先学习编码与解码。

编码:把字符串转换成字节数组,但是要按照某种编码方式

解码:按照与编码统一编码方式,把字节数组转换成字符串

但是编解码是码表用的不一致,会乱码。

字符流的存在是因为汉字占两个字节,用字节流操作我们还需要对汉字进行拆分与合并,,所以提供了字符流的操作。

字符流的继承关系:父类输入流抽象类:Reader。父类抽象类输出流:Writer

Reader的常见子类:BufferReader,InputstreamReader,StringReader.

Writer的常见子类:BufferWriter,OutputStreamWriter,StringWriter.

 String str="可乐";
        
        byte[] bytes = str.getBytes();
        System.out.println(Arrays.toString(bytes));

     
        String s = new String(bytes);
        System.out.println(s);

        String str2="中文乱码问题";
        //按照GBK来变得码
        byte[] gbks = str2.getBytes("UTF-8");
       
        String s1 = new String(gbks, "GBK");
        System.out.println(s1);
        //乱码出现的原因:就是编解码用的不是同一张码表

OutputStreamWriter
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 码表 将要写入流中的字符编码成字节。
它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

OutputStreamWriter(OutputStream out)
创建使用默认字符编码的 OutputStreamWriter。创建文件输出流,来关联文件,当关联的文件不存在时,会自动创建这个文件。

 OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("a.txt"));

OutputStreamWriter(OutputStream out, String charsetName)
创建使用指定字符集的 OutputStreamWriter。

 OutputStreamWriter out2 = new OutputStreamWriter(new FileOutputStream("a.txt"),"GBK");

在文件中写入数据

 OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("a.txt"));
        //一次写入一个字符
        out.write('我');
        out.flush();
        //写入换行符
        out.write("\r\n");
        //一次写入一个字符串
        out.write("你好,最近怎么样");
        out.write("\r\n");
        out.flush(); //字符流,要刷新,把缓冲区中的数据,刷新到磁盘中
        out.write("你好,最近怎么样");
        out.write("\r\n");
        //字符流,要刷新,把缓冲区中的数据,刷新到磁盘中
        out.flush();
        //释放资源
        out.close(); //刷新并关闭

追加写入:即在已有文件中追加内容,在相应的文件后追加true即可。(三种写入方法,与输入流类似)

 OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("c.txt",true));
        out.write("文字");
        out.write("\r\n");
        out.write('文字1');
        out.write("\r\n");
        //一次写入一个字符数组
        out.write(new char[]{'a', 'b', 'c', '既', '去'});
        out.write("\r\n");
        //一次写入字符串的一部分 从字符串的2索引出开始,写3个字符
        out.write("写入字符串的一部分", 2, 3);
        out.write("\r\n");
        //一次写入字符数组的一部分,从0索引处开始 写3个字符
        out.write(new char[]{'a', 'b', 'c', '哈', '哈'}, 0, 3);
        out.write("\r\n");
        //字符流,记得要刷新
        out.flush();
        //释放资源
        out.close();

输出流的异常处理:

 OutputStreamWriter out = null;
        try {
            out = new OutputStreamWriter(new FileOutputStream("c.txt", true));
            out.write("文字");
            out.write("\r\n");
            out.write('文字1');
            out.write("\r\n");
            //一次写入一个字符数组
            out.write(new char[]{'a', 'b', 'c', '以', '撒'});
            out.write("\r\n");
            //一次写入字符串的一部分 从字符串的2索引出开始,写3个字符
            out.write("写入字符串的一部分", 2, 3);
            out.write("\r\n");
            //一次写入字符数组的一部分,从0索引处开始 写3个字符
            out.write(new char[]{'a', 'b', 'c', '哈', '哈'}, 0, 3);
            out.write("\r\n");
            //字符流,记得要刷新
            out.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

文件的读取:

 InputStreamReader in = new InputStreamReader(new FileInputStream("e.txt"));
        //一次读取一个字符
        int ch = in.read();
        System.out.println(ch);
        ch = in.read();
        System.out.println(ch);
        ch = in.read();
        System.out.println(ch);
        ch = in.read();
        System.out.println((char) ch);
        ch = in.read();
        System.out.println((char) ch);
        ch = in.read();
        System.out.println((char)ch);
        //如果读取不到,就返回-1 我们就可以使用 -1 来判断这个文件是否读取完毕
        ch = in.read();
        System.out.println(ch);

       
        in.close();
 InputStreamReader in = new InputStreamReader(new FileInputStream("e.txt"));
        //定义一个字符数组来充当容器,可以一次取到这个容器中
        char[] chars=new char[1000];
        //一次读取1000个字符,放到字符数组中。返回值是实际读取到的字符个数
        int len = in.read(chars);
        System.out.println(len);
        System.out.println(Arrays.toString(chars));

 InputStreamReader in = new InputStreamReader(new FileInputStream("e.txt"));
        //定义一个字符数组来充当容器,可以一次取到这个容器中
        char[] chars = new char[1000];
        //一次读取一部分字符,放到字符数组中 从0索引处开始把读取到字符放进去 4 就是一次读去4个字符
        int len = in.read(chars,0,4);
        System.out.println(len);
        System.out.println(Arrays.toString(chars));
        in.close();

字符流的文件复制

  //使用字符流来复制文本文件
        InputStreamReader reader = new InputStreamReader(new FileInputStream("MyTest.java"));
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\aaa.java"));
        //读取一个字符,写一个字符来复制
        int ch=0;//用来记录每次读取到的字符
        while ((ch=reader.read())!=-1){
            writer.write(ch);
            writer.flush();//字符流记得读取一些字符就刷新
        }
     
        reader.close();
        writer.close();
        //为单个读取,效率底下,不建议。
//建议为一个数组的形式进行
        InputStreamReader reader = new InputStreamReader(new FileInputStream("MyTest.java"));
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\bbb.java"));

        char[] chars = new char[2000]; //定义一个字符数组,充当缓冲区
        int len=0;//用来记录实际读取到的字符个数
        int count=1;
        while ((len=reader.read(chars))!=-1){
            System.out.println("循环次数"+(count++));
            writer.write(chars,0,len);
            writer.flush();
        }

        reader.close();
        writer.close();

        System.out.println("复制完成");

文件复制时流的异常处理模块(同理)

 InputStreamReader reader = null;
        OutputStreamWriter writer = null;
        try {
           
            reader = new InputStreamReader(new FileInputStream("MyTest.java"));
            writer = new OutputStreamWriter(new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\bbb.java"));
         
            char[] chars = new char[2000];
            int len = 0;
            int count = 1;
            while ((len = reader.read(chars)) != -1) {
                System.out.println("循环次数" + (count++));
                writer.write(chars, 0, len);
                writer.flush();
            }

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

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        System.out.println("复制完成");
    }
}

FileWriter和FileReader复制文本文件

转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流提供了对应的子类。FileWriter与FileReader的便捷字符流

转换流 父类 便捷类 子类

OutputStreamWriter ------- FileWriter

InputStreamReader ------- FileReader

但是,便捷字符流,唯一就是不能指定编码 他自己也没有特有的方法,用的是继承下来的方法。

高效字符流:

BufferedReader (Reader in)

创建一个使用默认大小输入缓冲区的缓冲字符输入流

BufferedReader reader = new BufferedReader(new FileReader("MyTest.java"));

        char[] chars = new char[2000]; //定义一个字符数组,充当缓冲区
        int len = 0;//用来记录实际读取到的字符个数
        int count = 1;
        while ((len = reader.read(chars)) != -1) {
            System.out.println("循环次数" + (count++));
            writer.write(chars, 0, len);
            writer.flush();
        }

        reader.close();
        writer.close();

    }
}

BufferedWriter (Writer out)

创建一个使用默认大小输出缓冲区的缓冲字符输出流

BufferedWriter writer= new BufferedWriter(new FileWriter(“haha.java”));

高效的字符流BufferedReader 里面有特有的方法 String readLine() 一次读一行文本。

BufferedWriter void newLine() 写入一个换行符,具有平台兼容性。

  BufferedReader reader = new BufferedReader(new FileReader("MyTest.java"));

        BufferedWriter writer = new BufferedWriter(new FileWriter("hehe.java"));

        //循环的进行读取一行,写入一行
        //一行一行读取,读取不到返回的是null
        String line=null; //定义一个变量,来记录每次读取到的一行文本
        while ((line=reader.readLine())!=null){
            writer.write(line);
            //writer.write("\r\n");
            writer.newLine();
            writer.flush();
        }

        writer.close();
        reader.close();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值