过滤器
在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();
}