java基础:I/O学习笔记

I/O流

Java.io.file 文件类

File类是Java程序中表示文件和目录(文件夹)的方式,是文件和目录的路径名的抽象表示形式,我们可以使用File类对文件和文件夹进行操作。路径名是文件或目录的路径和名称的字符串形式。

我们可以使用File类的方法:

  1. 创建文件或文件夹
  2. 删除文件或文件夹
  3. 获取文件或文件夹
  4. 判断文件或文件夹是否存在
  5. 对文件夹进行遍历和筛选
  6. 获取文件的大小

File类的静态变量

  • static String pathSeparator: 与系统有关的文件名称分割分隔符,Windows系统是 ; Linux系统是 : 为了方便使用,它表示为一个字符串。源码:public static final String pathSeparator=""+pathSeparatorChar

  • static char pathSeparatorChar: 与系统有关的路径分隔符。

  • static String separator: 与系统有关的文件名称分割分隔符,Windows系统是 \ Linux系统是 / 为了方便使用,它表示为一个字符串。源码:public static final String Separator=""+SeparatorChar

  • static char separatorChar: 与系统有关的默认名称分割分隔符。

使用方法:

File类表示文件的方式是与系统无关的,但路径名表示文件的方式是与系统有关的,不同系统的文件名分割符不同,因此跨平台运行的Java软件的路径名需要用File类的静态变量代替字符分割符。

路径不区分大小写,Java中\表示转义字符,因此Windows上表示一个文件的路径,在Java程序中需要使用\\ 来表示\目录分隔符。

Windows写法:"C:\\java\\bin";Linux写法:"C:/java/bin"

通用写法:"C: "+File.separator+"java" +File.separator+"bin"

File类的构造方法

  • File(String pathname): 通过将参数传递的路径名字符串转换为抽象路径来创建一个的File类对象,表示一个文件或文件夹。String pathname: 字符串形式的路径名称,表示此File类对象的位置,该路径名最后一段是此File对象的名称。传递的可以是真路径也可以是假路径,可以是绝对路径也可以是相对路径,绝对路径是一个完整的路径,以盘符开始,相对路径是一个简化的路径,以当前目录为根目录开始。
File f1 = new File("C:\\Program Files\\MySQL");
System.out.println(f1); //File类重写了Object类的toString方法,所以直接打印File对象的引用会打印出构造方法中传递的路径名字符串 C:\Program Files\MySQL

File f0 = new File("C:\\Program Files\\SB");
System.out.println(f0); //不存在的SB文件夹,仍然打印出C:\\Program Files\\SB
  • File(String parent,String child): 根据parent父路径字符串和child子路径字符串创建一个File实例,好处是父路径和子路径可分开书写,父路径和子路径都可以单独变化,使用起来非常灵活。
String parent = "C:\\ProgramFiles\\";
File f2 = new File(parent, "MySQL");
File f3 = new File(parent, "Huawei");
System.out.println(f2);//C:\ProgramFiles\MySQL
System.out.println(f3);//C:\ProgramFiles\Huawei
  • File(File parent,String child): 根据parent抽象路径名和child子路径字符串创建一个File实例,好处是父路径和子路径可分开书写,父路径和子路径都可以单独变化,使用起来非常灵活。而且父路径是File类型,可以使用File方法对路径进行一些操作,再使用路径创建对象。
File parent = new File("C:\\ Program Files\\");
File f4 = new File(parent," MySQL");
File f5 = new File(parent," Huawei");
System.out.println(f4);//打印了 C:\Program Files\MySQL
System.out.println(f5);//打印了 C:\Program Files\ Huawei

File类常用方法

获取功能的方法

  • public String getAbsolutePath(): 返回此File对象的绝对路径名。无论构造方法中传递的路径是绝对的还是相对的,调用该方法获取的都是绝对路径名字符串。
File f1= new File("MySQL");
String path1=f1. getAbsolutePath ();
System.out.println(path1);//打印了 C:\\Program Files\\MySQL
  • public String getPath(): 获取此File对象的构造方法中传递的路径名字符串。File类的toString方法就调用了该方法,源码:public String toString(){return getPath();}
File f2= new File("Program Files\\MySQL");
String path2=f2. getPath ();
System.out.println(path1);//打印了 Program Files\\MySQL
  • public String getName(): 返回由此File对象表示的文件或文件夹的名称,即获取构造方法中传递的路径名的结尾部分。
File f1= new File("C:\\Program Files\\MySQL");
String name1=f1.getName();
System.out.println(name1);//打印了 MySQL
  • public long length () : 返回由此File对象表示的文件的大小,获取的是构造方法中指定的文件的大小,以字节为单位。文件夹没有大小,调用length () 方法返回0。如果构造方法中传递的路径不存在,调用length () 方法也返回0。
File f1 = new File("D:\\壁纸\\宝儿姐.jpg");
File f2 = new File("D:\\壁纸");
File f3 = new File("D:\\壁纸\\冯宝宝.jpg ");//没有这张照片
long size1 = f1.length();
long size2 = f2.length();
long size3 = f3.length();
System.out.println(size1);//打印了 125410(单位是字节)
System.out.println(size2);//打印了 0
System.out.println(size3);//打印了 0

判断类方法

  • public boolean exists (): 根据构造方法中传递的路径名(可以是相对路径名)判断此File对象表示的文件或文件夹(目录)是否存在。
  • public boolean isDirectory (): 根据构造方法中传递的路径名(可以是相对路径名)判断此File对象表示的是否是目录。
  • public boolean isFile (): 根据构造方法中传递的路径名(可以是相对路径名)判断此File对象表示的是否是文件夹。
  • 电脑的文件夹中只由文件和文件夹,所有以上两个方法是互斥的。使用这两个方法的前提是构造方法的路径必须存在。
File f1 = new File("C:\\Program Files\\MySQL");
if(f1.exists()){//判断MySQL是否存在
    boolean b1=f1.isFile();//判断是否是文件
    System.out.println(b1);}//打印出false

File f2 = new File("C:\\Program Files\\MySQL");
if(f2.exists()){//判断MySQL是否存在
    boolean b2=f2.isDirectory();//判断是否是文件夹
    System.out.println(b2);}//打印出true

创建和删除的方法

  • public boolean createNewFile() : 当且仅当此File对象表示的路径名的最后一段(即文件名)不存在时,创建一个由此路径名命名的空文件。注意:此方法声明了可能会抛出的异常IOException,当该File对象的路径不存在时,调用此方法会抛出异常,所以调用此方法时必须处理此异常。创建成功返回值为true,否则为false。
try { File f1 = new File("D:\\KuGou\\1.txt");
    boolean b1 = f1.createNewFile();
    System.out.println(b1); //创建成功,打印true
} catch (IOException e) { e.printStackTrace();}
  • public boolean mkdir() : 创建由此File对象表示的目录,只能创建单级文件夹。创建成功返回true,路径不存在不会抛出异常,也不会创建目录,返回值也是true,目录名已存在时返回false。
File f2 = new File("D:\\KuGou\\music");
boolean b2 = f2.mkdir();
System.out.println(b2); //创建成功,打印true
  • public boolean mkdirs(): 创建由此File对象表示的目录,包括任何必须但不存在的父目录。此方法可以创建多级文件夹。
File f3 = new File("D:\\KuGou\\music\\CantoneseSongs");
boolean b3 = f3.mkdir();
System.out.println(b3); //创建成功,打印true
  • public boolean delete(): 删除由此File对象表示的文件或目录。删除成功返回true,文件夹中有内容或构造方法中给出的路径不存在都返回false。注意:此方法直接从硬盘中删除文件或目录,不走回收站,谨慎使用。
File f4 = new File("D:\\KuGou\\music\\CantoneseSongs");
boolean b4 = f4.delete();
System.out.println(b4); //删除成功,打印true

遍历目录的方法

  • public String[] list() : 遍历此File对象表示的目录,获取目录中的文件和子目录的名称,并存储到一个String数组中作为返回值。如果构造方法中给出目录的路径不存在或不是目录(是文件)都会抛出空指针异常。
File f1 = new File("D:\\KuGou");
String[] list1 = f1.list();
for (String fileName : list1) {
    System.out.println(fileName); } //打印出该目录下所有文件和子目录的名称
  • public File[] listFiles(): 遍历此File对象表示的目录,获取目录中的文件和子目录的路径名,封装为File对象存储到一个File数组中作为返回值,新的File对象也可以调用File类的方法,因而用途更广。如果构造方法中给出目录的路径不存在或不是目录(是文件)都会抛出空指针异常。
File f2 = new File("D:\\KuGou");
File[] files = f2.listFiles();for (File file2 : files)   {  System.out.println(file2); } //调用了toString方法,打印出该目录下所有文件和子目录的路径名

递归打印多级目录:

public static void main(String[] args) {
        File f1 = new File("D:\\KuGou");
        getAllFile(f1);
    }
    public static void getAllFile(File dir){//定义递归方法
        System.out.println(dir);//打印参数中的目录路径名
        File[] files = dir.listFiles();//遍历参数中的目录,把该目录中的文件和子目录封装成File对象存储到File数组中
        for (File f2 : files) {//遍历File数组
            if (f2.isDirectory()){//判断数组元素是否是文件夹
                getAllFile(f2);}else {//把文件夹作为参数再调用本函数进行遍历
                System.out.println(f2);}//打印文件的路径名
                 } 
          }

递归搜索目录中的mp3文件:

public static void main(String[] args) {
    File f1 = new File("D:\\KuGou");
    getAllFile(f1);}
public static void  getAllFile(File dir){//定义递归方法
    File[] files = dir.listFiles();/*遍历参数中的目录,把该目录中的文件和子目录封装成File对象存储到File数组中*/
    for (File f2 : files) {//遍历File数组
        if (f2.isDirectory()){//判断数组元素是否是文件夹
            getAllFile(f2);}else //把文件夹作为参数再调用本函数进行遍历
        {
            String name = f2.getName();//获取此File对象的文件名并转换成字符串
            boolean b = name.endsWith(".mp3");//判断文件名的后缀名是否是.mp3
            if (b){System.out.println(f2);}//打印后缀名是.mp3的文件名。
/* D:\KuGou\music\download\祖娅纳惜 - 全都是戏.mp3
    D:\KuGou\music\download\祖娅纳惜 - 大氿歌.mp3
    D:\KuGou\music\download\祖娅纳惜 - 天下局.mp3
    D:\KuGou\music\download\祖娅纳惜 - 水上灯.mp3
    D:\KuGou\music\download\祖娅纳惜 - 百家策.mp3
    D:\KuGou\music\download\祖娅纳惜 - 繁华唱遍.mp3
    D:\KuGou\music\download\祖娅纳惜 - 苏幕遮.mp3
    */ }
    }
}

带过滤器的遍历方法

  • public File[] listFiles (FileFilter filter): 遍历此File对象表示的目录,获取目录中的文件和子目录的路径名,封装为File对象传递给参数中的过滤器,并把满足过滤规则的File对象存储到一个File数组中作为返回值。
  • Java.io.FileFilter: 文件过滤器接口,该接口只有一个抽象方法:boolean accept(File pathname)。使用此过滤器要创建该接口的实现类并重写此方法,自定义过滤规则,参数中的File对象满足过滤规则时返回值为true,否则为false。listFiles (FileFilter filter)方法会把遍历目录得到的每个File对象传递给FileFilter接口的实例的boolean accept(File pathname)方法并接收其返回值,返回值为true时,就会把此File对象存储到一个File数组中。

用过滤器搜索目录中大于10mb的文件:

public static void main(String[] args) {
    File f1 = new File("D:\\KuGou\\music");
    getAllFile(f1);
}
public static void getAllFile(File dir){
    File[] files = dir.listFiles(new FileFilter() {//创建一个文件过滤器接口的实现类(匿名内部类)
        @Override
        public boolean accept(File pathname) {//重写文件过滤器接口的accept方法
            if (pathname.isDirectory()) return true;
            /*如果此File对象是文件夹,则返回true,该文件夹会被放到File[]中继续遍历。*/
            return pathname.length()>10*1024*1024;
    /*如果此File对象大于10mb,则返回true,
    该文件会被放入File[]中。*/
        }
    }  );//
    /*遍历参数中的目录,把该目录中的文件和子目录封装成File对象传递给filter1()过滤器,把满足过滤规则的File对象存储到数组中*/
    for (File f2 : files) {//遍历File数组
        if (f2.isDirectory()) {getAllFile(f2);}//把是文件夹的File对象再调用本方法遍历
        else{
            System.out.println(f2);//把满足过滤条件的File对象打印出来
        }
    }
}

I/O流

流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。IO流就是以流的方式进行输入输出。Java程序通过IO流向内存,硬盘,网络等设备输入和输出数据。所谓的输入输出是相对程序而言的。

java.io.OutputStream 字节输出流

此抽象类是表示输出字节流的所有类的超类。定义了一些共性的成员方法:

  • public void close() : 关闭此输出流并释放与此流相关联的任何系统资源。
  • public void flush(): 刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void write(byte[] b): 将 b.length字节从指定的字节数组写入此输出流。
  • public void write(byte[] b, int off, int len): 从指定的字节数组写入 len个字节,从数组索引off开始输出到此输出流。
  • public abstract void write(int b): 将指定的字节写入此输出流。

重要子类:

java.io.FileOutputStream extends OutputStream

文件字节输出流,用于从内存中的程序向硬盘中的文件写入数据。

FileOutputStream类构造方法:

  • public FileOutputStream(String name): 创建一个FileOutputStream对象。根据构造方法中传递的路径名创建一个空的文件,如果存在同名的文件就覆盖旧的文件。把创建好的FileOutputStream对象指向创建好的文件。

  • public FileOutputStream(String name, boolean append): 第二个参数是续写开关,如果为true,就不覆盖同名旧文件,把此FileOutputStream对象指向旧文件的末尾。如果为false就和上面的方法一样。

  • public FileOutputStream(File file): 创建一个FileOutputStream对象并指向写入数据的文件。

  • public FileOutputStream(File file, boolean append): 第二个参数是续写开关,同上。

  • 输出数据的原理:(内存 > 硬盘)

    Java程序 > JVM(Java虚拟机)> OS(操作系统)> OS调研自己的输出数据方法 > 把程序中的数据写入到文件中

    硬盘中存储的数据都是以字节为基本单位的二进制整数,所以使用IO流输入输出的数据都是二进制整数,输入十进制整数会自动转换为二进制整数。一个字节用八位二进制整数表示(10101010),换算为十进制范围是-128127,更大的数据由多个字节组成,如一个int类型由四个字节(32位二进制数)组成。此方法的参数使用int类型是为了后续使用方便,其实在OutputStream接口的设计中定义了int类型只写入低8位二进制整数,高24位被忽略,所以参数还是一个字节,当int类型变量的值不超过-128127范围时int类型的高24位全都是0,被忽略也不影响,当int类型变量值超过 -128127范围时高24位不全为0,也就不止一个字节,但高24位被忽略了,有效值还是低8位表示的不超过-128127范围的整数,还是一个字节。

    Windows系统的记事本把十进制表示为0127的字节查询ASCII表显示,把十进制表示为-128-1的字节结合后一个字节查询系统默认码表(GBK)显示。

    public static void main(String[] args) throws IOException{//声明可能抛出的异常
    FileOutputStream fos1 = new FileOutputStream("D:\\KuGou\\a.txt");
        /* 创建一个FileOutputStream对象,参数中传递写入数据的目的地。a.txt是新建的文件,即使该文件存在依然会新建并覆盖旧的。*/
        char b1 = 'K';
        fos1.write(b1);/*char类型可以自动转换成int类型再被write()方法强制转化成字节,英文字符都使用ASCII编码,K对应ASCII表值为75,b1=75,75自动转换成二进制整数01001011写入a.txt,用记事本打开时会自动转换为十进制整数75查询ASCII表,显示K */
        char [] b2 = {'u','G','o','u'};
        for (int i = 0; i <4 ; i++) {
            fos1.write(b2[i]);
        }//一次一个字节,循环写入多个字节。此时用记事本打开a.txt显示KuGou
        fos1.close();/* 关闭此输出流并释放与此流相关联的任何系统资源。(流的使用会调用系统的方法,使用完毕关掉流能提高程序效率)*/
        File f1 = new File("D:\\KuGou\\a.txt");
        FileOutputStream fos2 = new FileOutputStream(f1,true);//创建一个FileOutputStream对象指向a.txt的末尾。
        int [] b3 = {50,48,50,48};
        for (int i = 0; i <4; i++) {
            fos2.write(b3[i]);
        }//50和48对应ASCII表值为2和0 ,此时用记事本打开a.txt显示KuGou2020。
        fos2.close();
        FileOutputStream fos3 = new FileOutputStream(f1);//创建一个FileOutputStream对象指向新的空文件a.txt,新的文件会覆盖旧文件。
        fos3.write(75);//此时用记事本打开a.txt显示K
        fos3.close();
    }
    
    

    FileOutputStream类常用方法:

    • public byte[] getBytes(): 使用平台的默认字符集将此String编码为字节序列,将结果存储到新的字节数组中。
    • public byte[] getBytes(String charsetName): 使用参数的字符串命名的字符集(编码表)将调用此方法的String转换为字节序列,将结果存储到新的字节数组中。
    • public static String toString(byte[] a): 将参数的字节数组的内容转换成字符串表示形式。 字符串表示由数组元素的列表组成,括在方括号 "[]" 中。 相邻的元素由字符", "分隔(逗号后跟一个空格)。
    public static void main(String[] args) throws IOException{//声明可能抛出的异常
        FileOutputStream fos = new FileOutputStream("D:\\KuGou\\a.txt");
       /* 创建一个FileOutputStream对象,构造方法中传递输出数据的目的地。a.txt是新建的文件,即使该文件存在依然会新建并覆盖旧的。*/
        byte [] b1 = "Music".getBytes();//把字符串按ASCII编码转换成字节序列并存储到新的字节数组中。
        byte [] b2 = " comes from life".getBytes();//空格也算一个字节。
        byte [] b3 = "生活".getBytes("GBK");//把字符串按GBK编码转换成字节序列并存储到新的字节数组中。
        System.out.println(Arrays.toString(b1));//[77, 117, 115, 105, 99]
        System.out.println(Arrays.toString(b2));//[32, 99, 111, 109, 101, 115, 32, 102, 114, 111, 109, 32, 108, 105, 102, 101]
        System.out.println(Arrays.toString(b3));//[-55, -6, -69, -18]
        fos.write(b1);/*把数组中的字节序列写入文件中。用记事本打开时会自动查询ASCII编码表,显示Music */
        fos.write(b2,0,12);/*把数组中从索引0~12的字节序列写入文件中。用记事本打开时会自动查询ASCII表,加上前面写入的显示Music comes from */
        fos.write(b3);/*把数组中的字节序列写入文件中。用记事本打开时遇到负数会自动结合后一个字节查询GBK编码表,加上前面写入的显示Music comes from 生活*/
        fos.close();
       /* 关闭此输出流并释放与此流相关联的任何系统资源。(流的使用会调用系统的方法,使用完毕关掉流能提高程序效率)*/
    }
    

    java.io.InputStream 字节输入流

    此抽象类是表示输出字节流的所有类的超类。定义了一些共性的成员方法:

    • public void close(): 关闭此输入流并释放与此流相关联的任何系统资源。
    • public int read(): 从该输入流读取一个字节的数据。
    • public int read(byte[] b): 从该输入流读取最多b.length字节的数据到字节数组。
    • public int read(byte[] b, int off, int len): 从该输入流读取最多len字节的数据为字节数组。

    Java.io.FileInputStream extends InputStream

    文件字节输入流,用于让内存中的程序从硬盘中的文件读取数据。

    FileInputStream类的构造方法:
    • FileInputStream(String name): 创建一个FileInputStream对象并指向参数传递的路径名表示的文件。

    • FileInputStream(File file): 创建一个FileInputStream对象并指向要读取的File对象表示的文件。

    • 输入数据的原理:(硬盘>内存)

      Java程序 > JVM(Java虚拟机)> OS(操作系统)> OS调研自己的输入数据方法 > 把文件的数据读取到程序中

    重写了父类的方法:
    • public int read(): 按顺序从该输入流指向的文件中读取一个字节并返回,读取一个字节后输入流会自动指向下一个字节,读到文件的末尾返回-1。
    public static void main(String[] args) throws IOException{//声明可能抛出的异常
        FileInputStream fis = new FileInputStream("D:\\KuGou\\a.txt");//此时用记事本
    打开a.txt显示KuGou2020
        /*创建一个FileInputStream对象并指向参数传递的文件a.txt*/
        int getByte = fis.read();//从a.txt读取一个字节作为返回值,用一个int变量接收。
        System.out.print((char) getByte);//读取到的字节的值为75,对应的ASCII编码表的值是'K',强制转换成char类型打印出K
        while ((getByte =fis.read())!=-1){//循环读取多个字节,每次循环读取一个字节,int变量只记录本次读取到的字节,下一循环重新赋值。read()方法读到文件末尾返回-1停止循环。
            System.out.print((char) getByte);//每读取一个字节就转换成字符打印一次。最终打印出KuGou2020
        }
        fis.close();
    }
    
    • public int read(byte[] b): 按顺序从该输入流指向的文件中读取最多b.length字节并存储到参数的字节数组中,参数中的数组起缓冲作用,数组的长度一般定义为1024(1kb)的整数倍。返回值是每次读取的有效字节数,读到文件的末尾返回-1。

    String类的构造方法:

    • [String](mk:@MSITStore:C:\Users\明月童子\Desktop\jdk api 1.8_google.CHM::/java/lang/String.html#String-byte:A-)(byte[] bytes): 通过使用平台的默认字符集解码将参数的字节数组用来构造新的String
    • [String](mk:@MSITStore:C:\Users\明月童子\Desktop\jdk api 1.8_google.CHM::/java/lang/String.html#String-byte:A-int-int-)(byte[] bytes, int offset, int length): 通过使用平台的默认字符集解码将参数的字节数组的一部分转换成字符串。offset:转换的开始索引,length:转换的字节个数。
    public static void main(String[] args) throws IOException{//声明可能抛出的异常
        FileInputStream fis = new FileInputStream("D:\\KuGou\\a.txt");//此时用记事本打开a.txt显示KuGou2020
        /*创建一个FileInputStream对象并指向参数传递的文件a.txt*/
        byte[] bytes = new byte[1024];//定义一个缓冲数组存储读取到的多个字节。
        int length ;//记录每次读取的有效字节个数。
        while ((length=fis.read(bytes))!=-1){//read(byte[] b)方法每次循环读取最多1024个字节,字节数组只记录本次循环读取到的字节,下一次循环重新赋值。读到文件末尾返回-1停止循环。
            System.out.println(new String(bytes,0,length));//把每读取到的length个字节一起转换成一个字符串打印出来。本次打印出KuGou2020
            System.out.println("本次读取字节数:"+length);//本次读取字节数:9
        }
        fis.close();
    }
    

    文件复制:一读一写

    public static void main(String[] args) throws IOException{//声明可能抛出的异常
        long s = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream("D:\\壁纸\\宝儿姐.jpg");/*创建一个FileInputStream对象,构造方法中绑定要读取数据的文件路径名*/
        FileOutputStream fos = new FileOutputStream("D:\\KuGou\\宝儿姐.jpg");/*创建一个FileOutputStream对象,构造方法中绑定要写入数据的文件路径名*/
        byte[] bytes = new byte[1024*10];//定义一个缓冲数组存储读取到的多个字节。
        int length ;//记录每次读取的有效字节个数。
        while ((length=fis.read(bytes))!=-1){/*read(byte[] b)方法每次循环从fis连接的文件读取最多1024*10个字节,缓冲数组只记录本次循环读取到的字节,下一次循环重新赋值。读到文件末尾返回-1停止循环。*/
            fos.write(bytes,0,length);/*write(byte[] b int off int len)方法每次循环将缓冲数组的length个字节写入fos创建的空文件,最后一次循环length可能小于缓冲数组的长度。*/
        } fis.close();fos.close();
        long e = System.currentTimeMillis();
        System.out.println("复制文件共耗时:"+(e-s)+" 毫秒");//复制文件共耗时:2毫秒
    }
    

    Java.io.Writer 字符输出流

    此抽象类是所有字符输入流的顶层父类,主要用于写入字符,中文日文等象形文字占一个字符两个字节,使用字符输出流比较方便。

    定义了一些共性的成员方法:

    • public void write(int c): 写入参数传递的一个字符,Writer类自动把参数中的int类型转换成char类型(忽略二进制的高16位)。
    • public void write(char[] cbuf): 写入参数传递的一个字符数组。
    • public abstract void write(char[] cbuf, int off, int len): 写入字符数组的一部分。
    • public void write(String str): 写入一个字符串。
    • public void write(String str, int off, int len): 写入一个字符串的一部分。
    • public abstract void flush(): 刷新该流的缓冲数据。write方法会先把字符写入缓冲区(字符转换成字节的过程),使用flush方法刷新后才会写入文件中。
    • public void close(): 先刷新该流的缓冲数据,然后关闭此输出流并释放与此流相关联的任何系统资源。

    Java.io.FileWriter extends OutputStreamWriter extends Writer

    文件字符输入流,用于把内存的程序的字符写入到硬盘的文件中。

    FileWriter类的构造方法:
  • FileWriter(File file): 创建一个FileWriter对象指向要写入字符的文件(File对象file代表的文件)。

  • FileWriter(File file boolean append): 第二个参数是续写开关,如果为true,就不覆盖同名旧文件,把此FileWriter对象指向旧文件的末尾。如果为false就和上面的方法一样。

  • FileWriter(String fileName): 创建一个FileWriter对象指向要写入字符的文件(路径名fileName代表的文件)。

  • FileWriter(String fileName boolean append): 同上。

Java.io.Reader 字符输入流

此抽象类是所有字符输入流的顶层父类,主要用于读取字符,中文日文等象形文字占一个字符两个字节,使用字符字符输入流比较方便。

定义了一些共性的成员方法:

  • public int read(): 读取一个字符并返回,char类型自动转换成int类型。如果读到字符串末尾返回-1。
  • public int read(char[] cbuf): 一次读取最多cbuf.length个字符,将字符存储到缓冲数组。返回读取的字符数,如果读到字符串末尾返回-1。
  • public abstract int read(char[] cbuf, int off, int len): 一次读取最多len个字符,将字符存储到缓冲数组,从数组的off索引开始。返回读取的字符数,如果读到字符串末尾返回-1。
  • public void close(): 关闭此输入流并释放与此流相关联的任何系统资源。如果读到字符串末尾返回-1。

Java.io.FileReader extends InputStreamReader extends Reader

文件字符输入流,用于把硬盘的文件读取到内存的程序中。

FileReader类的构造方法:
  • FileReader(File file): 创建一个FileReader对象指向要读取字符的文件(File对象file代表的文件)。
  • FileReader(String fileName): 创建一个FileReader对象指向要读取字符的文件(路径名fileName代表的文件)。
public static void main(String[] args) throws IOException {//声明可能抛出的异常
    FileWriter fw = new FileWriter("D:\\KuGou\\1.txt");//创建一个文件字符输出流对象指向文件1.txt
    char k = 'K';
    fw.write(k);
    fw.flush();/*向1.txt写入一个字符'K','K'会根据ASCII编码表转换成byte类型的正数'75',
    以二进制形式存储到硬盘的文件中,刷新后用记事本打开显示'K'*/
    char[] g = {'u', 'G', 'o', 'u'};
    fw.write(g);
    fw.flush();//向1.txt写入一个字符序列'u','G','o','u',刷新后用记事本打开显示KuGou
    String m = "Music";
    fw.write(m);
    fw.flush();/*向1.txt写入一个字符串"Music",其中每个字母都会根据ASCII编码表转换
    成byte类型的正数存储到硬盘的文件中,刷新后用记事本打开显示KuGouMusic*/
    String s = "就是歌多";
    fw.write(s);
    fw.flush();/*向1.txt写入一个字符串"就是歌多",其中每个中文占一个字符,每个字符
    都会根据BGK编码转换成两个byte类型的正数存储到硬盘的文件中,刷新后用记事本打开显示KuGouMusic就是歌多*/
    fw.close();
    FileReader fr = new FileReader("D:\\KuGou\\1.txt");//创建一个文件字符输入流,构造方法中绑定要读取字符的文件路径名
    int getChar;
    while ((getChar = fr.read()) != -1) {/*循环读取多个字符,每次循环读取一个字符,int变量只记录本次读取到的字符,
    下一循环重新赋值。read()方法读到文件末尾返回-1停止循环。*/
        System.out.print((char) getChar);/*每读取一个字符打印一次。最终打印出KuGouMusic就是歌多*/
    }
    fr.close();
    //复制一份中文资料。
    long s = System.currentTimeMillis();
    FileReader fr1 = new FileReader("D:\\乐器\\唢呐.txt");
    FileWriter fw1 = new FileWriter("D:\\KuGou\\唢呐.txt");
    char[] str = new char[1024*10];//定义一个缓冲数组存储读取到的多个字节。
    int lenth;//记录每次读取的有效字节个数。
    while ((lenth = fr1.read(str)) != -1) {/*read(char[] cbuf)方法每次循环从fr1
    连接的文件读取最多1024*10个字符,缓冲数组只记录本次循环读取到的字符,下一次循环重新赋值。读到文件末尾返回-1停止循环。*/
        fw1.write(str,0,lenth);/*write(char[] cbuf int off int len)方法每次循环将缓冲数组的length个字节
        写入fw1创建的空文件,最后一次循环length可能小于缓冲数组的长度。*/
    }fr1.close();fw1.close();
    long e = System.currentTimeMillis();
    System.out.println("复制文件共耗时:"+(e-s)+" 毫秒");//复制文件共耗时:2毫秒
}

猜你喜欢

转载自www.cnblogs.com/jinjun99/p/13384865.html