3.字符流

3.1、为什么会出现字符流

由于字节流操作中文不是特别方便,所以Java就提供字符流

  • 字符流=字节流+编码表

用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中,如何实现拼接的呢?

  • 汉字在存储时,无论选择哪种编码存储,第一个字节都是负数
package itheima06;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;

/*
一个汉字
    如果是GBK编码,占用2个字节   开头的字节都是负数
    如果是UTF-8编码,占用3个字节   开头的字节都是负数
*/
public class Demo01 {
    public static void main(String[] args) throws IOException {
/*//        FileInputStream fis=new FileInputStream("D:\\itcast\\java.txt");
        FileInputStream fis=new FileInputStream("myByteStream\\a.txt");
        int len;
//        byte [] bys=new byte[1024];
        while((len=fis.read())!=-1){
//            System.out.println(new String(bys,0,len));
            System.out.print((char) len);
        }
        fis.close();

 */
//        String s="abc";输出//[97, 98, 99]
        String s="中国";
//        byte[] bytes = s.getBytes();//一个汉字对应了三个UTF-8编码[-28, -72, -83, -27, -101, -67]
//        说明默认是UTF-8编码
//当我们指定GBK编码是,一个汉字对应的就是两个字节
//        byte[] bytes = s.getBytes("UTF-8");等价于 byte[] bytes = s.getBytes();
        byte[] bytes = s.getBytes("GBK");//[-42, -48, -71, -6]

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


    }
}

3.2、编码表

基础知识:

用什么字符集存储(编码),就用对用的字符集解码

字符集:系统支持的所有字符的集合,包括各国文字,标点、图形符号、数字

常见的字符集有

ASCII:

ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符。标准 ASCII 码也叫基础ASCII码,使用 7 位二进制数来表示所有的大写和小写字母,数字 0 到 9、标点符号, 以及在美式英语中使用的特殊控制字符。其中:

  0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(振铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;ASCII值为 8、9、10 和 13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。

  32~126(共95个)是字符(32sp是空格),其中48~57为0到9十个阿拉伯数字;

  65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。

  同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。

  后128个称为扩展ASCII码,目前许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展 ASCII 码允许将每个字符的第 8 位用于确定附加的 128 个特殊符号字符、外来语字母和图形符号。
GBXXX字符集

  • GB2312:简体中文码表,ASCII中有的127个称为半角字符,127以上的称为全角字符
  • GBK: 最常用的中文编码表,使用了双字节编码表方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等

Unicode字符集:

为了表达任意语言字符而设计,是业界的一种标准,也成为统一码,万国码。它最多使用4个字节的数字来表达每个字母、符号、或文字。有三种编码方案:UTF-8、UTF-16、UTF32.  UTF-8最常用

UTF-8

编码规则:

128个US-ASCII字符,只需一个字节编码

拉丁文等字符,需要两个字节编码

大部分常用语(含中文),使用三个字解码编码

其他极少数使用Unicode辅助字符,使用四字节编码

注:采用何种规则编码,就要采用对应的规则解码,否则就会出现乱码。

3.3、字符串中的编码解码问题

编码:
    byte[] getBytes() 使用平台的默认字符集(UTF-8)将该String编码为一系列字节,将结果存储到字节数组中
    byte[] getBytes(String CharStream) 使用指定的字符集,将该String编码为一系列字节,将结果存储到字节数组中
解码:
    String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的String
    String(byte[] bytes,String CharStream) 通过使用指定的字符集解码指定的字节数组来构造新的String

package com.itheima01;

/*
编码:
    byte[] getBytes() 使用平台的默认字符集(UTF-8)将该String编码为一系列字节,将结果存储到字节数组中
    byte[] getBytes(String CharStream) 使用指定的字符集,将该String编码为一系列字节,将结果存储到字节数组中
解码:
    String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的String
    String(byte[] bytes,String CharStream) 通过使用指定的字符集解码指定的字节数组来构造新的String
*/


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

public class StringDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
/*
//        默认UTF—8编码:
//        byte[] getBytes() 使用平台的默认字符集(UTF-8)将该String编码为一系列字节,将结果存储到字节数组中
        String s="我爱你";
        byte[] bytes = s.getBytes();
        System.out.println(Arrays.toString(bytes));
        //默认UTF-8每个字用三个数字表示[-26, -120, -111, -25, -120, -79, -28, -67, -96]

//        默认UTF-8解码:
//        String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的String
//        String ss=new String(bytes);
//        System.out.println(ss);//解码的结果为:  我爱你
        String sss=new String(bytes,"GBK");
        System.out.println(sss);//编码解码用的字节符不同时 的结果乱码: 鎴戠埍浣�
*/

//        GBK编码:
//       byte[] getBytes(String CharStream) 使用指定的字符集,将该String编码为一系列字节,将结果存储到字节数组中     byte[] getBytes() 使用平台的默认字符集(UTF-8)将该String编码为一系列字节,将结果存储到字节数组中
        String s="我爱你";
        byte[] bytes = s.getBytes("GBK");
        System.out.println(Arrays.toString(bytes));
        //GBK每个字用2个数字表示[-50, -46, -80, -82, -60, -29]

//        GBK解码:
//           String(byte[] bytes,String CharStream) 通过使用指定的字符集解码指定的字节数组来构造新的String String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的String
        String sss=new String(bytes,"GBK");
        System.out.println(sss);//解码结果乱码: 我爱你�


    }
}

3.4、字符流中的编码解码问题

字符流抽象基类

  • Reader:字符输入流的抽象类
  • Writer:字符输出流的抽象类

字符流中和编码解码问题相关的两个类

  • InputStreamReader 从字节流到字符流的桥梁
  • OutputStreamWriter
package com.itheima02;

/*
InputStreamReader  是从字节流到字符流的桥梁
        他读取字节,并使用指定的编码将其解码为字符
        它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
OutputStreamWriter 是从字符流到字节流的桥梁
        使用指定的编码将写入的字符编码为字符
        它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
*/

import java.io.*;
import java.util.Arrays;

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

//        OutputStreamWriter(OutputStream out)创建一个默认字符编码的OutputStreamWriter
//        OutputStreamWriter(OutputStream out,String charsetName)创建一个指定字符编码的OutputStreamWriter
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"),"GBK");
//       当我们指用GBK编码字符串"中国" 写数据
        osw.write("中国");//编码的结果就是   �й�
        osw.close();
//        InputStreamReader(InputStream in) 创建一个默认字符集的InputStreamReader
//        InputStreamReader(InputStream in,Stirng CharsetName) 创建一个默认字符集的InputStreamReader
        InputStreamReader isr=new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"),"GBK");
//       一次读取一个字符,需要读两次,第一次读"中","国"
       /* int ch= isr.read();
        System.out.println((char) ch);
        ch= isr.read();
        System.out.println((char) ch);*/
//       一次读取字符数组
        int ch;
        while ((ch=isr.read())!=-1)
        {
            System.out.print((char) ch);//�й�
        }
//优化改进一次读一个数组
      /*  int len;
        byte[] bys=new byte[1024];
        while((len=isr.read(bys))!=-1){
//            System.out.println(len);
            System.out.println(new String(bys,0,len));

        }*/

/*
        int len;
        byte [] bys=new byte[1024];
        while((len= bis.read(bys))!=-1){
            System.out.print(new String(bys,0,len));
        }
*/

        isr.close();
    }
}

3.5、字符流写数据的5种方式

void writer (int c) 写一个字符
void writer (char[] cbuf)   写一个字符数字
void writer (char[] cbuf,int off,int len)   写入一个字符数组的一部分
void writer (String str)    写一个字符串
void writer (String str,int off,int len) 写入一个字符串的一部分
package com.itheima03;
/*

构造方法:
        InputStreamReader(InputStream in) 创建一个试用默认字符集的InputStreamReader
读数据的2种方式
        int read()一次读一个字符数据
        int read(char[] cbuf)一次读一个字符数组数据

*/

import java.io.*;

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
//        先写一个GBK编码的文件,然后再用InpuStreamReader来读数据
        OutputStreamWriter osw2=new OutputStreamWriter(new FileOutputStream("myCharStream\\osw2.txt"),"GBK");
//        void writer (int c) 写一个字符
        String s1="我";
        String s2="爱";
        String s3="你";
        osw2.write(s1);
        osw2.write(s2);
        osw2.write(s3);

        osw2.close();
  /*      InputStreamReader isr=new InputStreamReader(new FileInputStream("myCharStream\\osw2.txt"),"GBK");
//        int read()一次读一个字符数据
 *//*       int ch;

        while((ch= isr.read())!=-1){
            System.out.print((char) ch);
        }*//*
//        int read(char[] cbuf)一次读一个字符数组数据
//        String[] s=new String[1024];
        char [] chs=new char[1024];
        int len;
        while((len= isr.read(chs))!=-1){
//            把一个字符串数组转换成字符
            System.out.print(new String(chs,0,len));
        }*/

//        重新问一个文件读取数据
        InputStreamReader isr=new InputStreamReader(new FileInputStream("myCharStream\\ConversionStreamDemo.java"));
//        int read()一次读一个字符数据
 /*       int ch;

        while((ch= isr.read())!=-1){
            System.out.print((char) ch);
        }*/
//        int read(char[] cbuf)一次读一个字符数组数据
//        String[] s=new String[1024];
        /*char [] chs=new char[1024];
        int len;
        while((len= isr.read(chs))!=-1){
//            把一个字符串数组转换成字符
            System.out.print(new String(chs,0,len));



        }*/
        copy();
    }
//创建一个方法用来copy  ConversionStreamDemo.java 并将改文件复制到copy.java中
    public static void copy() throws IOException {
//        先用InputStreamReader读取ConversionStreamDemo.java文件
        InputStreamReader isr=new InputStreamReader(new FileInputStream("myCharStream\\ConversionStreamDemo.java"));
//        然后用OutputStreamWriter将ConversionStreamDemo.java文件字节流写入copy.java中
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("myCharStream\\copy.java"));



        char[] chs=new char[1024];
        int len;
        while((len= isr.read(chs))!=-1)
        {
            System.out.println(new String(chs,0,len));
            osw.write(chs);
        }

        isr.close();
        osw.close();



    }



}

案例:

需求:把目录下的ConversionStreamDemo.java复制到模块目录下的copy.java
        用了两个子类简化创建对象
        FileReader  替代InputStreamReader  但是有缺点就是不能用来指定字符集
        FileWriter 替代OutputStreamWriter 但是有缺点就是不能用来指定字符集

package com.itheima03;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
需求:把目录下的ConversionStreamDemo.java复制到模块目录下的copy.java
        用了两个子类简化创建对象
        FileReader  替代InputStreamReader  但是有缺点就是不是能用来指定字符集
        FileWriter 替代OutputStreamWriter 但是有缺点就是不是能用来指定字符集

*/

public class copyDemo {
    public static void main(String[] args) throws IOException {
        FileReader fr=new FileReader("myCharStream\\ConversionStreamDemo.java");
        FileWriter fw=new FileWriter("myCharStream\\copy.java");
        char[] chs=new char[1024];
        int len;
        while((len=fr.read(chs))!=-1){
            fw.write(chs,0,len);
        }
        fr.close();
        fw.close();

    }
}

3.7、字符缓冲流


BufferedWriter 将文本写入字符输出流,缓冲字符,以提供单个字符,
        数组和字符串的高效写入,可以制定缓冲区大小,或者接收默认大小(默认足够大)
BufferedReader 从字符输入流读取文本,缓冲字符,以提供字符,
        数组和行字符串的高效读取,可以制定缓冲区大小,或者接收默认大小(默认足够大)
构造方法:
        BufferedWriter(Writer out)
        BufferedReader(Reader in)


案例需求:把目录下的ConversionStreamDemo.java复制到模块目录下的copy.java

package com.itheima04;
/*
需求:把目录下的ConversionStreamDemo.java复制到模块目录下的copy.java
BufferedWriter 将文本写入字符输出流,缓冲字符,以提供单个字符,
        数组和字符串的高效写入,可以制定缓冲区大小,或者接收默认大小(默认足够大)
BufferedReader 从字符输入流读取文本,缓冲字符,以提供字符,
        数组和行字符串的高效读取,可以制定缓冲区大小,或者接收默认大小(默认足够大)
构造方法:
        BufferedWriter(Writer out)
        BufferedReader(Reader in)
*/


import java.io.*;

public class BufferedDemo {
    public static void main(String[] args) throws IOException {
        long starTime=System.currentTimeMillis();

        buffered();



        long endTime=System.currentTimeMillis();
        System.out.println("用字符缓冲流写的程序耗时:"+(endTime-starTime)+"毫秒");
    }

    public static void buffered() throws IOException {
        BufferedWriter bw=new BufferedWriter(new FileWriter("myCharStream\\copy.java"));
        BufferedReader br=new BufferedReader(new FileReader("myCharStream\\ConversionStreamDemo.java"));
//        一次读取一个字符数据
     /*   int ch;
        while((ch= br.read())!=-1){
//            System.out.println((char) ch);
            bw.write(ch);
        }*/
        char[] chs=new char[1024];
        int len;
        while((len= br.read(chs))!=-1){
            bw.write(chs,0,len);
        }
//        一次读取一个字符串数据
        bw.close();
        br.close();

    }
}

3.8、字符缓冲流特有功能

字节串缓冲流的特有功能

BufferedWriter
                void newLine() 写一行行分隔符,行分隔符字符串由系统属性定义
        
BufferedReader
                public String readLine() 读一行文字
                结果包括行的内容的字符串,不包括任何行终止符,如果流已到达结尾,则为null

package com.itheima04;
/*

字节串缓冲流的特有功能
        BufferedWriter
                void newLine() 写一行 行分隔符,行分隔符字符串由系统属性定义
        BufferedReader
                public String readLine() 读一行文字
                结果包括行的内容的字符串,不包括任何行终止符,如果流已到达结尾,则为null
*/

import java.io.*;

public class BufferedStreamDemo {
    public static void main(String[] args) throws IOException {
    /*    BufferedWriter bw=new BufferedWriter(new FileWriter("myCharStream\\bw.txt"));
        for (int i=0;i<3;i++){
            bw.write("hello"+i);
//            bw.write("\r\n");
//            void newLine() 写一行行分隔符,行分隔符字符串由系统属性定义
//            bw.newLine();
            bw.flush();
        }

        bw.close();*/

//        BufferedReader
        BufferedReader br=new BufferedReader(new FileReader("myCharStream\\bw.txt"));
//        public String readLine() 读一行文字
//        结果包括行的内容的字符串,不包括任何行终止符,如果流已到达结尾,则为null
/*//        第一次读取数据---应该读的是第一行的数据
        String line1 = br.readLine();
        System.out.println(line1);
//        第二次读取数据---应该读的是第2行的数据
        String line2 = br.readLine();
        System.out.println(line2);
//        第3次读取数据---应该读的是第3行的数据
        String line3 = br.readLine();
        System.out.println(line3);
//        第4次读取数据---没有内容是输出null
        String line4 = br.readLine();
        System.out.println(line4);*/
//循环改进
        String line;
        while((line=br.readLine())!=null){

//            System.out.print(line);  该方法不会读取换行符所以需要手动换行
            System.out.println(line);
        }


        br.close();
    }
}

案例:复制单极文件夹

package com.itheima09;
/*

需求:把"D:\\itcast"这个文件夹复制到模块目录下
思路:
    创建数据源目录File对象,路径是D:\\itcast
    获取数据源目录File对象的名称(itcast)
    创建目的地目录File对象,路径名是模块名+itcast组成(myCharStream\\itcast)
    判断目的地目录对应的File是否存在,如果不存在,就创建
    获取数据源目录下所有文件的File数组
    遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
        数据源文件:D:\\itcast\\lala.jpg
    获取数据源文件File对象的名称(lala.jpg)
    创建目的地文件File对象,路径名是目的地目录+lala.jpg组成(myCharStream\\itcast\\lala.jpg)
    复制文件
            由于文件不仅仅是文本文件,还有图片、视频,所以采用字节流复制文件
*/


import java.io.*;

public class CopyFolderDemo {
    public static void main(String[] args) throws IOException {
//        创建数据源目录File对象,路径是D:\\itcast
        File srcFolder=new File("D:\\itcast");
//        获取数据源目录File对象的名称(itcast)
        String srcFolderName=srcFolder.getName();
//        System.out.println("源目录名:"+srcFolderName);
//        创建目的地目录File对象,路径名是模块名+itcast组成(myCharStream\\itcast)
        File destFolder=new File("myCharStream",srcFolderName);
//        判断目的地目录对应的File是否存在,如果不存在,就创建
        if(!destFolder.exists())
        {
            destFolder.mkdir();
        }
//                获取数据源目录下所有文件的File数组
        File [] listFile=srcFolder.listFiles();
//        遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
        for(File srcFile :listFile)
        {
//        数据源文件:D:\\itcast\\lala.jpg
//        获取数据源文件File对象的名称(lala.jpg)
            String srcFileName=srcFile.getName();
//            System.out.println(srcFileName);
//        创建目的地文件File对象,路径名是目的地目录+lala.jpg组成(myCharStream\\itcast\\lala.jpg)
            File destFile=new File(destFolder,srcFileName);
            //        复制文件
            copyFile(srcFile,destFile);
        }
//        由于文件不仅仅是文本文件,还有图片、视频,所以采用字节流复制文件
    }
     public static void copyFile(File srcFile,File destFile) throws IOException {
//        使用字节缓冲流写文件
         BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(destFile));
//         使用字节缓冲流读取数据
         BufferedInputStream bis=new BufferedInputStream(new FileInputStream(srcFile));
         int len;
         byte[] bys=new byte[1024];
         while((len= bis.read(bys))!=-1)
         {
             bos.write(bys);
         }
         bis.close();
         bos.close();
     }
}

案例:复制多级文件

package com.itheima09;
/*需求:复制多级目录
思路:
①创建数据源File对象,路径是D:\\itcast
②创建目的地File对象,路径C:
③写方法实现文件夹的复制,参数为数据File对象和目的地Fiie对象
④判断数据源File是否是目录
        是目录:
                在目的地下创建和数据源File名称一样的目录
                获取数据源File下所有数组,得到每一个File对象
                遍历File数组,得到每一个File对象
                把该File作为数据源File对象,递归调用复制文件夹的方法
        不是目录
                说明File对象是文件,直接调用方法复制,用字节流*/
import java.io.*;
public class CopyMultiFolderDemo {
    public static void main(String[] args) throws IOException {
//创建数据源File对象,路径是D:\\itcast
        File srcFolder=new File("D:\\itcast");
//创建目的地File对象,路径C:\\
        File destFolder=new File("C:\\");
//写方法实现文件夹的复制,参数为数据File对象和目的地Fiie对象
        copyFolder(srcFolder,destFolder);
    }
//复制文件夹
    private static void copyFolder(File srcFolder,File destFolder) throws IOException {
        //判断数据源File是否是目录
        if (srcFolder.isDirectory())
        {
//        是目录:
//            在目的地下创建和数据源File名称一样的目录
            String srcFolderName = srcFolder.getName();
//            获取D盘相同的文件名
            File newFileName=new File(destFolder,srcFolderName);// itcast
            System.out.println("从D盘复制过来的目录名:"+newFileName);
//            再次判断一下C盘有没有itcast这个文件,确保c盘有File newFileName=new File(destFolder,srcFolderName);// itcast文件
           /* 从D盘复制过来的目录名:C:\itcast
            从D盘复制过来的目录名:C:\itcast\JavaSE
            从D盘复制过来的目录名:C:\itcast\JavaWEB
            从D盘复制过来的目录名:C:\itcast\JavaWEB\HTML*/
            if (!newFileName.exists()){
                newFileName.mkdir();
            }
//          获取数据源File下 所有数组,得到每一个File对象
            File[] fileArray = srcFolder.listFiles();//C:\\itcast
//                遍历File数组,得到每一个File对象
            for (File file:fileArray)
            {
                System.out.println("数据源File下所有:"+file);
//              需要将遍历获取的File对象封装起来
//                String.valueOf(file)
//        把该File作为数据源File对象,递归调用复制文件夹的方法  下一层级如果还是目录还是继续递归
                copyFolder(file,newFileName);
//                File destFile=new File(newFileName, file);
            }
        }else{
//        不是目录
//      说明File对象是文件,直接调用方法复制,用字节流
//            copyFile(源文件,目的地文件);这里的文件名每一此次都会变,所以需要封装起来
            File newFile=new File(destFolder,srcFolder.getName());
            copyFile(srcFolder,newFile);
        }
    }
//复制文件
    public static void copyFile(File srcFile,File destFile) throws IOException
    {
//        使用字节缓冲流写文件
         BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(destFile));
//         使用字节缓冲流读取数据
         BufferedInputStream bis=new BufferedInputStream(new FileInputStream(srcFile));
         int len;
         byte[] bys=new byte[1024];
         while((len= bis.read(bys))!=-1)
         {
             bos.write(bys);
         }
         bis.close();
         bos.close();
     }
}

3.9、字节流报错处理

package com.itheima10;

/*
try{
    可能出现异常的代码
        }catch{
    异常的处理代码
        }finally{
    执行所有清楚操作
        }
*/

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

public class CopyFileDemo {
    public static void main(String[] args)throws IOException {
        method1();
        method2();
    }
    //    抛出异常的标准写法JDK9   会自动释放资源
    public static void method4() throws IOException{
        FileReader fr=new FileReader("fr.txt");
        FileWriter fw=new FileWriter("fw.txt");
        try(fr; fw;){
            char[] chs = new char[1024];
            int len;
            while ((len = fr.read(chs)) != -1)
            {
                fw.write(chs, 0, len);
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }
    //    抛出异常的标准写法JDK7   会自动释放资源
    public static void method3() {
        try(FileReader fr=new FileReader("fr.txt");
            FileWriter fw=new FileWriter("fw.txt");){
            char[] chs = new char[1024];
            int len;
            while ((len = fr.read(chs)) != -1)
            {
                fw.write(chs, 0, len);
            }
        }
        catch(IOException e){
            e.printStackTrace();
            }
        }
           /* fr.close();
            fw.close();*/
//    抛出异常的标准写法try{..}catch(){...}finally
    public static void method2() {
        FileReader fr=null;
        FileWriter fw=null;
        try{
            fr = new FileReader("fr.txt");
            fw = new FileWriter("fw.txt");
            char[] chs = new char[1024];
            int len;
            while ((len = fr.read(chs)) != -1) {
                fw.write(chs, 0, len);
            }
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            if (fr!=null)
            {
                try{
                    fr.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
            if(fw!=null)
            {
                try{
                    fw.close();

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

        }
    }
//    抛出异常,调用方法时还需要抛出一次异常
    public static void method1()throws IOException {
        FileReader fr = new FileReader("fr.txt");
        FileWriter fw = new FileWriter("fw.txt");
        char[] chs = new char[1024];
        int len;
        while ((len = fr.read(chs)) != -1) {
            fw.write(chs, 0, len);
        }
        fr.close();
        fw.close();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值