Java多线程与IO流学习笔记(四)
File类
概述
java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建,查找和删除等操作。
File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法。
pathSeparator和separator:
- Windows:路径分隔符是分号(;),文件名分隔符是反斜杠()
- Linux:路径分隔符是冒号(:),文件名分隔符是斜杠(/)
- 路径不能写死
路径:
- 绝对路径:是一个完整的路径
- 相对路径:是一个简化的路径,相对于当前项目的根目录
注意:
- 路径是不区分大小写
- windows系统下路径分隔符反斜杠是转义字符要写两个来表示一个。
构造方法
- public File(String pathname): 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例。
- public File(String parent,String child):从父路径名字符串和子路径名字符串创建新的File实例。
- public File(File parent,String child):从父抽象路径名和子路径名字符串创建新的File实例
路径可以是存在也可以是不存在,创建File对象,只是把字符串封装为File对象,不考虑路径的真假情况。
常用方法
获取功能的方法:
- public String getAbsolutePath():返回此File的绝对路径名字符串
- public String getPath():将此File转换给路径名字符串
- public String getName():返回由此File表示的文件或目录的名称
- public long length():返回由此File表示的文件的长度
判断功能的方法:
- public boolean exists():表示文件或目录是否实际存在。
- public boolean isDirectory():判断是否为目录
- public boolean isFile():判断是否为文件
创建和删除功能的方法:
- public boolean createNewFile():当且仅当具有该名称的问价不存在时,创建一个新的空文件
- public boolean delete():删除此File表示的文件或目录
- public boolean mkdir():创建由此file表示的目录
- public boolean mkdirs():创建由此File表示的目录,包括任何必须但不存在的父目录。
目录的遍历
- public String[] list():返回一个String数组,表示该File目录中的所有子文件或目录。
- public File[] listFiles():返回一个File数组,表示该File目录中所有的子文件或目录。
如果路径不存在或路径不是一个目录,会抛出空指针异常
文件过滤器
java.io.FileFilter 是一个接口,是File的过滤器。 该接口的对象可以传递给File类的 listFiles(FileFilter) 作为参数, 接口中只有一个方法。
boolean accept(File pathname) :测试pathname是否应该包含在当前File目录中,符合则返回true。
- 接口作为参数,需要传递子类对象,重写其中方法。我们选择匿名内部类方式,比较简单。
- accept 方法,参数为File,表示当前File下所有的子文件和子目录。保留住则返回true,过滤掉则返回
false。保留规则:- 要么是.java文件。
- 要么是目录,用于继续遍历。
- 通过过滤器的作用, listFiles(FileFilter) 返回的数组元素中,子文件对象都是符合条件的,可以直接打
印。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class DiGuiDemo4 {
public static void main(String[] args) {
File dir = new File("D:\\aaa");
printDir2(dir);
}
public static void printDir2(File dir) {
// 匿名内部类方式,创建过滤器子类对象
File[] files = dir.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.getName().endsWith(".java")||pathname.isDirectory();
}
});
// 循环打印
for (File file : files) {
if (file.isFile()) {
System.out.println("文件名:" + file.getAbsolutePath());
} else {
printDir2(file);
}
}
}
}IO概述
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 length):从指定的字节暑促写入len字节,从偏移量off开始输出到此输出流。
- public abstract void write(int b):将指定的字节输出流
close方法,当完成流的操作时,必须调用此方法,释放系统资源
数据的追加续写:
每次程序运行,创建输出流对象,都会清空目标文件中的数据。如何保留目标文件中数据,还能 继续添加新数据呢?
public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的 文件。
public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。 这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。
1
2
3
4
5
6
7
8
9
10
11
12
13/**
* FileOutputStream:文件字节输出流
* 作用:把内存中的数据写入到硬盘的文件中
*/
public class Demo01OutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("/Users/zhangyun/Desktop/javaTest/a.txt",true);
byte[] bytes = ",憨憨".getBytes();
System.out.println(Arrays.toString(bytes));
fos.write(bytes);
fos.close();
}
}FileOutputStream类
OutputStream 有很多子类,我们从最简单的一个子类开始。
java.io.FileOutputStream 类是文件输出流,用于将数据写出到文件。
构造方法public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。参数是文件的路径。
构造方法的作用:
- 创建一个FileOutputStream对象
- 会根据构造方法中传递的文件/文件路径,创建一个空的文件
- 会把FileOutputStream对象指向创建好的文件
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。
1 | /** |
写出换行
回车符 \r 和换行符 \n :
- 回车符:回到一行的开头(return)。
- 换行符:下一行(newline)。
系统中的换行:
- Windows系统里,每行结尾是 回车+换行 ,即 \r\n ; - Unix系统里,每行结尾只有换行,即 \n ;
- Mac系统里,每行结尾是回车,即 \r 。从 Mac OS X开始与Linux统一。
字节输入流
java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入
流的基本共性功能方法。
- public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
- public abstract int read() : 从输入流读取数据的下一个字节。
- public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组b中 。
FileInputStream类
java.io.FileInputStream 类是文件输入流,从文件中读取字节。
构造方法
- FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系 统中的 File对象 file命名。
- FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件 系统中的路径名 name命名。
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出 FileNotFoundException 。
读取字节数据
- 读取字节: read 方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1。
- 使用字节数组读取: read(byte[] b) ,每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读
取到末尾时,返回-1
字符流
当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为 一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。
字符输入流Reader
java.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入
流的基本共性功能方法。
- public void close() :关闭此流并释放与此流相关联的任何系统资源。
- public int read() : 从输入流读取一个字符。
- public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中。
FileReader类
java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
构造方法
- FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
- FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个文件路径。类似于FileInputStream。
读取字符数据
- read方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取
使用字符数组读取:
read(char[] cbuf) ,每次读取b的长度个字符到数组中,返回读取到的有效字符个数,读取到末尾时,返回-1。
1 | public class Demo01OutputStream { |
字符输出流
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 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
构造方法
- FileWriter(File file) : 创建一个新的FileWriter,给定要读取的File对象。
- FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。
字符输出流的使用步骤
- 创建FileWriter对象,构造方法中绑定要写入数据的目的地。
- 使用FileWriter中的write方法,把数据写入到内存缓冲区中。
- 使用FileWriter中的flush方法,把内存缓冲区中的数据,刷新到文件中
- 释放资源(会把内存缓冲区的数据刷新到文件中)
1 | public class Demo01OutputStream { |
实际上应该使用try-catch和finally来确保流被关闭。
1 | public class Demo01OutputStream { |
对try-catch的改进
JDK7的改进:
在try的后面增加一个括号,在括号中定义流对象,那么这个流对象的作用域就在try中有效,try中的代码执行完毕,会自动把流对象释放,不用再写finally
1 | try(FileWriter fw = new FileWriter("/Users/zhangbin/Desktop/javaTest");){ |
JDK9的新特性:
try的前面可以定义流对象,在try后面的括号中可以直接引入流对象的变量名,在try代码执行完毕后,流对象也可以释放掉,不用写finally。
属性集
概述
java.util.Properties 继承于 Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时,System.getProperties 方法就是返回一个Properties对象。
Properties类
构造方法
- public Properties() :创建一个空的属性列表。
基本的存储方法
- public Object setProperty(String key, String value) : 保存一对属性。
- public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
- public Set
stringPropertyNames() :所有键的名称的集合。
1 | private static void show01() { |
与流相关的方法
- public void load(InputStream inStream) : 从字节输入流中读取键值对。
- public void load(Reader reader)
- public void store(OutputStream outStream,String comments):把集合中的临时数据,持久化写入到硬盘中存储;
- public void store(Writer writer,String comments)
参数:
OutputStream outStream:字节输出流,不能写入中文;
Writer writer:字符输出流,可以写中文。
comments:注释,用来解释说明保存的文件是做什么用的,不能使用中文,会产生乱码,默认是Unicode编码,一般使用“”空字符串
使用步骤:
- 创建Properties集合对象,添加数据
- 创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地。
- 使用Properties中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
- 释放资源
1 | private static void show02() throws IOException { |
缓冲流
概述
缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
- 字节缓冲流: BufferedInputStream , BufferedOutputStream
- 字符缓冲流: BufferedReader , BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO 次数,从而提高读写的效率。
字节缓冲流
构造方法:
- public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
- public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
参数加 int size 会指定缓冲流大小,不加为默认大小。
字符缓冲流
构造方法:
- public BufferedReader(Reader in) :创建一个 新的缓冲输入流。
- public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。
特有方法:
- BufferedReader: public String readLine() : 读一行文字。
- BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。