java的文件和IO流

过滤器

在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器
File[] listFiles(FileFilter filter)

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

File[] listFiles(FilenameFilter filter)

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

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

IO流

IO流的分类

参考学习:https://www.cnblogs.com/QQ846300233/p/6046388.html

根据处理数据类型的不同分为:字符流和字节流
根据数据流向不同分为:输入流和输出流

字符流和字节流
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:

(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。

结论: 优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
在这里插入图片描述

注:使用字节流读取中午,会产生乱码
GBK:占两个字节; UTF-8:占三个字节

字节输出流: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) :将指定的字节输出流。

子类:

FileOutputStream类:文件字节输出流,将内存中的数据写入到文件中
构造方法:
public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) : 创建文件输出流以指定的路径写入文件。
FileOutputStream(String name, boolean append): 创建文件输出流以指定的名称写入文件。

当创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。

// 使用方式
FileOutputStream fos = new FileOutputStream("H:\\编程学习\\java一\\java_test\\a.txt");
fos.write(97);
byte[] bytes = {65, 66, 67, 68, 69};
fos.write(bytes); // 写入字节数组
fos.write(bytes, 2, 2); // 从第二个位置,写2个字节

byte[] bytes1 = "你好".getBytes();
fos.write(bytes1); // 写入字符串

fos.close();
private static void fun2() throws IOException {
    FileOutputStream fos = new FileOutputStream("H:\\编程学习\\java一\\java_test\\c.txt", true); // 追加写
    byte[] bytes = {65, 66, 67, 68, 69};
    fos.write(bytes);
    for (int i = 0; i < 10; i++) {
        fos.write("你好\r\n".getBytes()); // 写入你好加换行
    }
    fos.close();
}

一次写多个字节:
如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII码表
如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中午显示,查询系统默认码表(GBK)

字节输入流:IntputStream

基本共性方法:

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

子类:

FileInputStream类:文件字节输入流,把硬盘中的数据读取到内存中使用
构造方法:
FileInputStream(File file); 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(String name); 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

// 使用方法
FileInputStream fis = new FileInputStream("H:\\编程学习\\java一\\java_test\\a.txt");
int len = 0;
len = fis.read();
System.out.println(len);
while ((len = fis.read()) != -1) {
    System.out.print((char)len);
}
fis.close();
private static void func2() throws IOException {
    FileInputStream fis = new FileInputStream("H:\\编程学习\\java一\\java_test\\b.txt");
    byte[] bytes = new byte[1024];
    int len = 0;
    while ((len = fis.read(bytes)) != -1) {
        System.out.println(new String(bytes, 0, len));
    }
    fis.close();
}

int read(byte[] b); 从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
byte[]的作用:起到缓冲作用,存储每次读取到的多个字节;
数组的长度一般定义为1024(1kb)或者1024的整数倍

字符输入流:Reader

java.io.Reader 抽象类
基本共性方法:
int read(); 读一个字符
int read(char[] cbuf); 一次读取多个字符将字符读入数组。
abstract void close(); 关闭流并释放与之相关联的任何系统资源。

子类 FileReader

java.io.FileReader extends InputStreamReader extends Reader
把硬盘文件中的数据以字符的方式读取到内存中
构造方法:
FileReader(File file); 创建一个新的 FileReader ,给出 File读取。
FileReader(String fileName); 创建一个新的 FileReader ,给定要读取的文件的名称。

FileReader fr = new FileReader("H:\\编程学习\\java一\\java_test\\b.txt");
//        int len = 0;
//        while ((len = fr.read()) != -1) {
//            System.out.print((char)len);
//        }

char[] cs = new char[1024];
int len = 0;
while ((len = fr.read(cs)) != -1) {
    System.out.print(new String(cs, 0, len));
}
fr.close();

字符输出流:Writer

java.io.Writer抽象类
基本共性方法:

void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract void write(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

java.io.FileWriter extends OutputStreamWriter extends Writer
把内存中的字符数据写入到文件中

构造方法:
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。

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

FileWriter fw = new FileWriter("H:\\编程学习\\java一\\java_test\\c.txt");
fw.write(97);
fw.flush();
fw.close();

flush :刷新缓冲区,流对象可以继续使用。
close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

JDK7新特性:流的try…catch
try中的代码执行完毕,会自动把流对象释放,不要再写finally

/*
try(定义流对象; 定义流对象;...) {
    可以会产生异常的代码
} catch (异常类变量 变量名) {
    异常的处理逻辑
}
*/
        try (FileWriter fw = new FileWriter("H:\\编程学习\\java一\\java_test\\c.txt");) {
            fw.write(97);
        } catch (IOException e) {
            System.out.println(e);
        }

Properties类

java.util.Properties extends Hashtable<Object,Object> extends Map<K,V>
Properties集合是唯一一个和IO流相结合的集合
基本的存储方法 :

public Object setProperty(String key, String value) : 调用Hashtable方法 put
public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
public Set<String> stringPropertyNames() :返回所有键的名称的集合,相当于Map中的keySet()方法

void store(OutputStream out, String comments); 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法加载到 Properties表中的格式输出流。
void store(Writer writer, String comments); 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式输出到输出字符流。
void load(InputStream inStream); 从输入字节流读取属性列表(键和元素对)。
void load(Reader reader); 以简单的线性格式从输入字符流读取属性列表(关键字和元素对)。
    private static void show02() throws IOException {
        // 1.创建Properties集合对象,添加数据
        Properties prop = new Properties();
        prop.setProperty("赵丽颖", "168");
        prop.setProperty("杨幂", "167");
        prop.setProperty("迪丽热巴", "169");

        // 2.创建字节流输出流/字符输出流对象,构造方法中绑定要输出的目的地
        FileWriter fw = new FileWriter("H:\\编程学习\\java一\\java_test\\prop.txt");

        // 使用Properties集合中的store,把集合中的临时数据,持久化写入到硬盘中存储
        prop.store(fw, "save data");

        // 4.释放资源
        fw.close();
    }
    private static void show03() throws IOException {
        Properties prop = new Properties();
        FileReader fr = new FileReader("H:\\编程学习\\java一\\java_test\\prop.txt");
        prop.load(fr);

        Set<String> set = prop.stringPropertyNames();
        for (String key : set) {
            String value = prop.getProperty(key);
            System.out.println(key + "=" + value);
        }
    }

缓冲流

  • 字节缓冲流: BufferedInputStream, BufferedOutputStream
  • 字符缓冲流: BufferedReader, BufferedWriter

缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO 次数,从而提高读写的效率。

字符缓冲流

特有方法
字符缓冲流的基本方法与普通字符流调用方式一致,不再阐述,我们来看它们具备的特有方法。

  • BufferedReader: public String readLine() : 读一行文字。
  • BufferedWriter: public void - newLine() : 写一行行分隔符,由系统属性定义符号。

转换流

转换流 java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。
使用指定的字符集将字符 编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。
构造方法:

  • OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。
  • OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流

转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。
它读取字节,并使用指定 的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集
构造方法:

  • InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。
  • InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。(需要和文件的编码相同)

例:将GBK编码文件转换为utf-8编码文件

private static void func01() throws IOException {
    InputStreamReader isr = new InputStreamReader(
            new FileInputStream("H:\\编程学习\\java一\\java_test\\gbk.txt"), "GBK");
    OutputStreamWriter osw = new OutputStreamWriter(
            new FileOutputStream("H:\\编程学习\\java一\\java_test\\gbktoutf_8.txt"), "utf-8");
    int len = 0;
    while ((len = isr.read()) != -1) {
        osw.write(len);
    }
    isr.close();
    osw.close();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值