0
点赞
收藏
分享

微信扫一扫

Java基础知识——File类与IO流

言诗把酒 2022-01-24 阅读 65

文章目录


一、File类

1、File类的静态成员变量

  • static String pathSeparator:与系统有关的路径分隔符,为了方便,它被表示成一个字符串。window:分号 linux:冒号
  • static String separator:与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。windows:反斜杠\ linux:正斜杠/

2、File类的构造方法

  • File(String pathname):通过给定路径名字符串转换为抽象路径名来创建一个新File实例
  • File(String parent , String child):将路径分为两部分,更加灵活,传入两部分的字符串来创建新File实例
  • File(URI uri):通过给定的file:URI转换为一个抽象路径名来创建一个新的File实例

3、File类的常用方法

  • public String getAbsolutePath():返回此File的绝对路径名字符串
  • public String getPath():将此File转换为路径名字符串
  • public String getName():返回由此File表示的文件或目录名称
  • public long length():返回由此File表示的文件的长度,以字节为单位。如果路径不存在,则返回0;文件夹没有大小,返回的也是0
  • public boolean exists():此File表示的文件或者目录是否真实存在
  • public boolean isDirectory():此File是否为目录
  • public boolean isFile():此File表示的是否为文件
  • public boolean createNewFile():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。创建文件的路径和名称在构造方法中给出
File f = new f(文件路径);
boolean b = f.createNewFile();
  • public boolean delete():删除由此File表示的文件或目录。删除文件夹时如果文件夹中有内容则不会删除并返回false。直接在硬盘删除,不走回收站。
  • public boolean mkdir():创建由此File表示的目录
  • public boolean mkdirs():创建由此File表示的目录包括任何必须但不存在的父目录
  • public String[] list():返回一个String数组,表示该File目录中的所有子文件或者目录。获取所有名称,将所有子文件或者目录名称转为字符串存入String数组
  • public File[] listFiles():返回一个File数组,表示该File目录中的所有子文件或者目录

注:list()和listFiles()方法遍历的是构造方法中给出的目录。如果构造方法中给出的目录的路径不存在,会抛出空指针异常。当路径不是一个目录时,也会抛出空指针异常

4、过滤器

  • File[] listFiles(FileFilter filter):
    java.io.Filefilter接口:用于抽象路径名(File对象)的过滤器。用来过滤文件(File对象)。boolean accept(File pathname)方法用于测试指定抽象路径名是否应该包含在某个路径名参数列表中。pathname是使用ListFiles方法遍历目录,得到的每一个文件对象。

  • File[] listFiles(FilenameFilter filter)
    java.io.FilenameFilter接口:用于此接口的类实例可以用于过滤器文件名。作用是用来过滤文件名称。boolean accept(File dir , String name)测试指定文件是否应该包含在某一个文件列表。dir是构造方法中传递的被遍历的的目录。name是使用listFiles方法遍历目录,获取的每一个文件或文件夹的名称。

注:两个过滤器接口是没有实现类的,需要我们自己写实现类,并且重写accept方法,自己定义过滤的规则

FileFilter过滤器:

package File;

import java.io.File;
import java.io.FileFilter;
import java.util.Locale;

//目标:获得指定文件夹下的所有java文件(包括文件和目录中的文件)
public class Filter {
    public static void main(String[] args) {
        File file = new File("c:\\abc");
        getAllFile(file);
    }

    static void getAllFile(File dir){
        File[] files = dir.listFiles(new FileFilterImpl());//传递过滤器对象
        /*
         *listFiles做了三件事:
         * 1、对构造方法中传递的目录进行遍历,获取目录中的每一个文件/文件夹封装为File对象
         * 2、调用参数传递的过滤器中的accept方法
         * 3、会把遍历得到的每一个File对象传递过accept方法的参数pathname
         * accept方法会返回一个布尔值,如果是true则将传递过去的File对象存到File数组中,如果是false就不会保存到File数组中
         */
        for(File f: files){
            if(f.isDirectory()){
                getAllFile(f);
            }else{
                System.out.println(f);
            }
        }
    }
}

//创建FileFilter的实现类
class FileFilterImpl implements FileFilter {
    public boolean accept(File pathname){
        /*
         * 过滤规则:
         * 在accept方法中,判断File对象是否以.java结尾
         */
        //如果pathname是一个文件夹,返回true,继续遍历这个文件夹
        if(pathname.isDirectory())
            return true;
        return pathname.getName().toLowerCase().endsWith(".java");
    }
}

FilenameFilter:

package File;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Locale;

public class FilenameFiler {
    public static void main(String[] args) {
        File file = new File("c:\\abc");
        getAllFile(file);
    }

    static void getAllFile(File dir){
       File[] files = dir.listFiles(new FilenameFilter(){
           public boolean accept(File dir,String name){
               return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".java");
           }
       });
        for(File f: files){
            if(f.isDirectory()){
                getAllFile(f);
            }else{
                System.out.println(f);
            }
        }
    }
}

二、IO概述

根据读写数据不同,可以分为字符流和字节流:一个字符=两个字节

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

1、字节输出流(OutputStream)

  • void close():关闭此输出流并释放与此流有关的所有系统资源
  • void flush():刷新此输出流并强制写出所有缓冲的输出字节
  • void write(byte[] b):将b.length个字节从指定的数组写入此输出流
  • void write(byte[] b , int off , int len):将指定的数组从偏移量off开始的len个字节写入此输出流
  • abstract void write(int b):将指定的字节写入此输出流

FileOutputStream:文件字节输出流
FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流。是将数据写出到目的地name(文件的路径)中
FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流。将数据写出到目的地file文件中

package File;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class Demo1OutputStream {
    public static void main(String[] args) throws IOException {
        //1、创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
        FileOutputStream fos = new FileOutputStream("a");
        //2、调用write方法,将数据写入文件中
        fos.write(97);
        byte[] bytes = "你好".getBytes();
        fos.write(bytes);
        //3、释放资源
        fos.close();
    }
}


用上述方法向文件中写入数据时,下一次会将这些数据重写一遍再写入新的数据从而覆盖掉旧数据。因此,就有了文件续写:
FileOutputStream(String name , boolean append)
FileOutputStream(File file , boolean append)
当append为true时:表示创建对象不会覆盖源文件,继续在文件的末尾追加数据
否则,将创建一个新的文件,覆盖源文件

2、字节输入流(InputStream)

  • int read():从输入流中读取数据的下一个字节。读到末尾的时候返回-1
  • int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
  • void close():关闭此输入流并释放与该流关联的所有系统资源

FileInputStream:文件字节输入流
FileInputStream(String name)
FileInputStream(File file)

一次读取多个字节:

package File;

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

public class Demo1InputStream {
    public static void main(String[] args) throws IOException {
        //1、创建FileInputStream对象
        FileInputStream fis = new FileInputStream("a.txt");
        //int read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
        byte[] bytes = new byte[2];
        int len = fis.read(bytes);//读取的有效字节个数
        System.out.println(len);
        System.out.println(new String(bytes));
        //释放资源
        fis.close();
    }
}

文件复制:

package File;

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

/*
* 文件复制的步骤:
*   1、创建一个字节输入流对象,构造方法中绑定要读取的数据源
*   2、创建一个字节输出流对象,构造方法中绑定要写入的目的地
*   3、使用字节输入流对象中的方法read读取文件
*   4、使用字节输出流中的方法write,把读取到的字节写入到目的地
*   5、释放资源
*/
public class CopyFile {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("c:\\1.jpg");
        FileOutputStream fos = new FileOutputStream("d:\\1.jpg");
        byte[] bytes = new byte[1024];
        int len = 0;
        while((len = fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
        fos.close();
        fis.close();
    }
}

3、字符输入流(Reader)

  • int read():读取单个字符并返回
  • int read(char[] cbuf):一次读取多个字符,将字符存入数组
  • void close():关闭该流并释放与之关联的所有资源

FileReader:文件字符输入流,将硬盘文件中的数据以字符的方法读取到内存中
FileReader(String fileName)
FileReader(File file)

package File;

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

public class DemoReader {
    public static void main(String[] args) throws IOException {
        //1、创建FileReader对象,构造方法中绑定要读取的数据源
        FileReader fr = new FileReader("c:\\a.txt");
        //2、使用read方法读取文件
        int len = 0;
        while((len = fr.read())!=-1){
            System.out.println(len);
        }
        //3、释放资源
        fr.close();
    }
}

4、字符输出流(Writer)

  • void write(int c):写入单个字符
  • void write(char[] cbuf):写入字符数组
  • abstract void char(char[] cbuf , int off , int len):写入字符数据的一部分,off数组的开始索引,len写的字符的个数
  • void write(String str):写入字符串
  • void write(String str , int off , int len):写入字符串的一部分,off字符串的开始索引,len写的字符个数
  • void flush():刷新该流的缓冲
  • void close():关闭此流,但要先刷新它

FileWriter:文件字符输出流
FileWriter(File file)
FileWriter(String fileName)
FileWriter(File file , boolean append)
FileWriter(String fileName , boolean append)

字符输出流的使用步骤(重点):

  1. 创建FileWriter对象,构造方法中绑定要写入数据的目的地
  2. 使用FileWriter中的方法write,将数据写入到内存缓冲区中(字符转换为字节的过程)
  3. 使用FileWriter中的方法flush,把内存缓冲区中的数据刷新到文件中
  4. 释放资源(会把内存缓冲区中的数据刷新到文件中 )

5、Properties集合

java.util.properties集合 extends HashTable<k,v> implements Map<k,v>
Properties类表示了一个持久的属性集。Properties可保存在流中或从流中加载。
Properties集合是唯一 一个和IO流相结合的集合。可以使用其中的方法store把集合中的临时数据持久化写入到硬盘中存储。可以使用其中的方法load把硬盘中保存的文件(键值对)读取到集合中使用。key和value默认都是字符串。

  • Object setProperty(String key , String value):调用HashTable的方法put
  • String getProperty(String key):通过key找到value值,此方法相当于Map集合中的get(key)方法
  • Set< String > stringPropertyNames():返回此属性列表中的键集存储到一个Set集合
package File;

import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

/*
    可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
    void store(OutputStream out , String comments)
    void store(Writer writer , String comments)
    参数:
        OutputStream out :字节输出流,不能写入中文
        Writer writer : 字符输出流,可以写中文
        String comments : 注释,用来解释说明保存的文件是做什么用的
                            不能使用中文,会产生乱码,一般使用空字符串
     使用步骤
        1、创建Properties集合对象,添加数据
        2、创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
        3、使用方法store,把集合中的临时数据持久化写入到硬盘中存储
        4、释放资源
 */
public class DemoStore {
    public static void main(String[] args) throws IOException {
        Properties prop = new Properties();
        prop.setProperty("李明","96");

        FileWriter fw = new FileWriter("c:\\b.txt");

        prop.store(fw,"save data");

        fw.close();
    }
}

package File;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

/*
    可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对)读取到集合中使用
    void load(InputStream inStream)
    void load(Reader reader)
    参数:
        InputStream inStream : 字节输入流,不能读取含有中文的键值对
        Reader reader :字符输入流,能读取含有中文的键值对
     使用步骤:
        1、创建Properties集合对象
        2、使用load方法读取保存键值对的文件
        3、遍历Properties集合
     注意:
        1、存储键值对的文件中,键与值默认的连接符号可以使用=、空格
        2、存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
        3、存储键值对的文件中,键与值默认都是字符串,不用再加引号
 */
public class DemoLoad {
    public static void main(String[] args) throws IOException {
        Properties prop = new Properties();
        prop.load(new FileReader("d:\\a.txt"));
        Set<String> set = prop.stringPropertyNames();
        for(String key : set) {
            String value = prop.getProperty(key);
            System.out.println(key+"="+value);
        }
    }
}

6、缓冲流

6.1 字节缓冲输出流(BufferedOutputStream)

package File;

import java.awt.image.DataBufferDouble;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/*
    BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流,以将数据写入指定的底层输出流
    BufferedOutputStream(OutputStream out , int size):创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流
    参数:
        OutputStream out : 字节输出流,我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高写入效率
        int size:指定缓冲流内部缓冲区的大小,不指定则默认
    使用步骤:
        1、创建FileOutputStream对象,构造方法中绑定要输出的目的地
        2、创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream对象效率
        3、使用BufferedOutputStream对象中的方法write,将数据写入到内部缓冲区
        4、使用BufferedOutputStream对象中的方法flush,把内部缓冲区的数据刷新到文件中
        5、释放资源(会先调用flush方法去刷新数据,因此第四步可以省略)
 */
public class DemoBufferedOutputStream {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("c:\\a.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write("我把数据写入到内存缓冲区:".getBytes());
        bos.flush();
        bos.close();
    }
}

6.2字节缓冲输入流(BufferedInputStream)

package File;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

/*
    BufferedInputStream(InputStream in):创建一个输入流in
    BufferedInputStream(InputStream in , int size):创建具有指定缓冲区大小的输入流
    参数:
        InputStream in :我们可以传递FileInputStream,缓冲流会给FileInputStream增加一个缓冲区,提高读取效率
        int size:指定缓冲流内部缓冲区的大小,不指定默认
    使用步骤:
        1、创建FileInputStream对象,构造方法中绑定要读取的数据
        2、创建BufferedInputStream对象,构造方法中传递FileInputStream对象
        3、使用BufferedInputStream对象中的方法read读取文件
        4、释放资源
 */
public class DemoBufferedInputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("c:\\a.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        byte[] bytes = new byte[1024];
        int len = 0 ;
        while((len = bis.read())!=-1){
            System.out.println(new String(bytes,0,len));
        }
        bis.close();
    }
}

6.3 字符缓冲输出流(BufferedWriter)

package File;

import com.company.Task4_3;

import java.io.BufferedWriter;
import java.io.IOException;

/*
    BufferedWriter(Writer out):创建一个使用默认大小输出缓冲区的缓冲字符输出流
    BufferedWriter(Writer out , int size):一个使用给定大小输出缓冲区的缓冲字符输出流

    特有的成员方法:
        void nextLine():写入一个行分隔符。会根据不同的操作系统获取不同的行分隔符

    使用步骤:
        1、创建字符缓冲输出流对象,构造方法中传递字符输出流
        2、调用字符缓冲输出流中的方法write,将数据写入到内存缓冲区中
        3、调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据刷新到文件中
        4、释放资源
 */
public class DemoBufferedWriter {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\d.txt"));
        for(int i = 0 ; i < 10 ; i++){
            bw.write("写入数据");
            bw.newLine();
        }
        bw.flush();
        bw.close();
    }
}



6.4字符缓冲输入流(BufferedReader)

package File;

import com.company.Task4_3;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/*
    BufferedReader(Reader in):创建一个使用默认大小输入缓冲区的缓冲字符输入流
    BufferedReader(Reader in , int size):创建一个使用指定大小输入缓冲区的缓冲字符输入流

    特有方法:
        String readLine():读取一行数据,行的终止符号为换行('\n')、回车('\r')或者回车后直接跟着换行。
                            返回值:包含该行内容的字符串,不包含任何终止符。如果已经到达末尾,则返回null

    使用步骤:
        1、创建字符缓冲输入流对象,构造方法中传递字符输入流
        2、使用字符缓冲输入流中的方法read/readLine读取文本
        3、释放资源
 */
public class DemoBufferedReader {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("c:\\d.txt"));
        String line;
        while((line = br.readLine())!= null)
            System.out.println(line);
        br.close();
    }
}

7、转换流

在IDEA中,使用FileReader读取项目中的文本文件。由于IDEA的设置都是默认的UTF-8编码,所以没有任何的问题。但是读取Windows系统中创建的文本文件时,由于Windows系统默认的是GBK编码,因此会出现乱码问题。为了解决这个问题,就需要引入转换流。

7.1OutputStreamWriter

package File;

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

/*
    java.io.OutputStreamWriter extends Writer
    OutputStreamWriter:是字符流通向字节流的桥梁,可使用指定的charset将要写入流中的字符编码成字节

    构造方法:
        OutputStreamWriter(OutputStream out):创建使用默认字符编码的OutputStreamWriter
        OutputStreamWriter(OutputStream out , String charsetName):创建使用指定字符集的OutputStreamWriter
        参数:
            OutputStream out:字节输出流,可以用来写转换之后的字节到文件中
            String charsetName:指定的编码表名称,不区分大小写

    使用步骤:
        1、创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
        2、使用OutputStreamWriter对象中的方法write,把字符转换成为字节存储在缓冲区中(编码)
        3、使用OutputStreamWriter对象中的方法flush,将内存缓冲区中的字节刷新到文件中
        4、释放资源
 */
public class DemoOutputStreamWriter {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c:\\d.txt"),"GBK");
        osw.write("你好");
        osw.flush();
        osw.close();
    }
}

7.2 InputStreamReader

package File;

import java.io.*;

/*
    java.io.InputStreamReader extends Reader
    InputStreamReader:是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符

    构造方法:
        InputStreamReader(InputStream in)
        InputStreamReader(InputStream in , String charsetName)
        参数:
            InputStream in: 字节输入流,用来读取文件中保存的字节
            String charsetName:指定的编码表名称,不区分大小写

    使用步骤:
        1、创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
        2、使用InputStreamReader对象中的方法read读取文件
        3、释放资源
    注:构造方法中指定的编码表名称要和文件的编码相同,否则会出现乱码
 */
public class DemoInputStreamReader {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("c:\\d.txt"),"UTF-8");
        int len = 0 ;
        while((len = isr.read())!=-1)
            System.out.println((char)len);
        isr.close();
    }
}

8、序列化

对象的序列化和反序列化,对象类要实现Serializable接口

注:不想某个成员被序列化时,可以在这个成员添加transient关键字

8.1 对象的序列化(ObjectOutputStream)

package File;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

/*
    java.io.ObjectOutputStream extends OutputStream
    ObjectOutputStream:对象的序列化流
    作用:把对象以流的方式写入到文件中保存

    构造方法:
        ObjectOutputStream(OutputStream out)

    特有的成员方法
        void writeObject(Object obj):将指定的对象写入流中

    使用步骤:
        1、创建ObjectOutputStream对象,构造方法中传递字节输出流
        2、使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
        3、释放资源
 */
public class DemoObjectOutputStream {
    public static void main(String[] args) {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("c:\\d.txt"));
        oos.writeObject(new Person("李明"),18);
        oos.close();
    }
}

8.1 对象的反序列化(ObjectInputStream)

/*
    java.io.ObjectInputStream extends InputStream
    ObjectInputStream:对象的反序列化流,把文件中保存的对象以流的方式读取出来

    构造方法:
        ObjectInputStream(InputStream in)

    特有方法:
        Object readObject()

    使用步骤:
        1、创建ObjectInputStream对象,构造方法中传递字节输入流
        2、使用ObjectInputStream对象中的方法readObject读取保存对象的文件
        3、释放资源
        4、使用读取出来的对象
 */
举报

相关推荐

0 条评论