Java中File的使用
File构造方法
- File();
- File(String fileName);
- File(File parent,String child);
- FIle(String parent,String child)
File类获取功能的方法
- public string getAbsolutePath():返回此FiLe的绝对路径名字符串。
- public string getPath() :将此FiLe转换为路径名字符串。
- public string getName():返回由此File表示的文件或目录的名称。
- public long length() :返回由此FiLe表示的文件的长度。
File判断功能的方法
- public boolean exists() :此File表示的文件或目录是否实际存在。
- public boolean isDirectory () :此FiLe表示的是否为目录。
用于判断构造方法中给定的路径是否以文件夹结尾
是:true
否:false - public boolean isFile() :此FiLe表示的是否为文件。
用于判断构造方法中给定的路径是否以文件结尾
是:true
否:false
注意:
电脑的硬盘中只有文件/文件夹,两个方法是互斥
这两个方法使用前提,路径必须是存在的,否则都返回false
File类创建删除功能的方法
- public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
注意:
- 此方法只能创建文件,不能创建文件夹
- 创建文件的路径必须存在,否则会抛出异常
- public boolean delete() :删除由此File表示的文件或目录。
- public boolean mkdir() :创建由此FiLe表示的目录。
- public boolean mkdirs ()∶创建由此FiLe表示的目录,包括任何必需但不存在的父目录。
File类遍历(文件夹)目录功能
- public String[ ] list()︰返回一个String数组,表示该FiLe目录中的所有子文件或目录。
- public File[ ] listFiles()︰返回一个FiLe数组,表示该FiLe目录中的所有的子文件或目录。
注意:
list方法和ListFiles方法遍历的是构造方法中给出的目录
如果构造方法中给出的目录的路径不存在,会抛出空指针异常
如果构造方法中给出的路径不是一个目录,也会抛出空指针异常
过滤器
在File类中有两个ListFiles重载的方法,方法的参数传递的就是过滤器File[]、listFiles(FileFilter filter)
- java.io.FileFilter接口:用于抽象路径名(FiLe对象)的过滤器。
作用:用来过滤文件(FiLe对象)
抽象方法:用来过滤文件的方法
boolean accept(File pathname)测试指定抽象路径名是否应该包含在某个路径名列表中。
参数:
File pathname:使用ListFiles方法遍历目录,得到的每一个文件对象
File[] listFiles ( FilenameFilter filter)
File file = new File("Day06\\src\\abc.txt");
//递归打印出文件夹下所有的文件并使用过滤器,只留下txt文件
// printAllFile(file, new FileFilter() {
// @Override
// public boolean accept(File pathname) {
// return pathname.getName().endsWith("txt") || pathname.isDirectory();
// }
// });
//简化
printAllFile(file, pathname -> pathname.getName().endsWith("txt") || pathname.isDirectory() );
private static void printAllFile(File file, FileFilter fileFilter) {
File[] files = file.listFiles(fileFilter);
if (file.isFile()){
return;
}
for (File file1 : files) {
if (file1.isFile()) {
System.out.println(file1.getAbsolutePath());
}else{
printAllFile(file1,fileFilter);
}
}
}
- java.io.FiLenameFilter接口:实现此接口的类实例可用于过滤器文件名。
作用:用于过滤文件名称
抽象方法:用来过滤文件的方法
boolean accept(File dir,String name)测试指定文件是否应该包含在某一文件列表中。
参数:
File dir:构造方法中传递的被遍历的目录
String name :使用ListFiLes方法遍历目录,获取的每一个文件/文件夹的名称
File file = new File("Day06\\src\\abc.txt");
// printAllFile(file, new FilenameFilter() {
// @Override
// public boolean accept(File dir, String name) {
// return new File(dir,name).getName().endsWith("txt") || new File(dir,name).isDirectory();
// }
// });
printAllFile(file, ( dir, name) -> new File(dir,name).getName().endsWith("txt") || new File(dir,name).isDirectory());
//重载一个带FilenameFilter过滤器的方法
private static void printAllFile(File file, FilenameFilter fileFilter) {
File[] files = file.listFiles(fileFilter);
if (file.isFile()){
return;
}
for (File file1 : files) {
if (file1.isFile()) {
System.out.println(file1.getAbsolutePath());
}else{
printAllFile(file1,fileFilter);
}
}
}
注意:
两个过滤器接口是没有实现类的,需要我们自己写实现类,重写过滤的方法accept,在方法中自己定义过滤的规则
必须明确两件事情:
- 过滤器中的accept方法是谁调用的
- accept方法的参数pathname是什么?
listFiles方法一共做了3件事情:
- listFiles方法会对构造方法中传递的目录进行遍历,获取目录中的每一个文件/文件夹–>封装为File对象
- listFiles方法会调用参数传递的过滤器中的方法accept
- listFiles方法会把遍历得到的每一个File对象,传递过accept方法的参数pathname
文件输入输出流
字节输出流
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:文件字节输出流
作用:把内存中的数据写入到硬盘的文件中构造方法:
FileoutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。
FiLeOutputStream(File file) 创建一个向指定File对象表示的文件中写入数据的文件输出流。
参数:写入数据的目的地
string name:目的地是一个文件的路径
File file:目的地是一个文件
构造方法的作用:
- 创建一个Fileoutputstream对象.
- 会根据构造方法中传递的文件/文件路径,创建个空的文件
- 会把FileoutputStream对象指向创建好的文件
public void write(byte[] b): 将b.length字节从指定的字节数组写入此输出流。一次写多个字节:
- 如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
- 如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)
可以用Debug,验证
将"你好"转化为Bytes数组
public void write(byte[] b, int off, int len): 把字节数组的一部分写入到文件中
int off:数组的开始索引
int len:写几个字节
追加写
追加写/续写:使用两个参数的构造方法
FileOutputStream(String name, boolean append) 创建一个向具有指定name的文件中写入数据的输出文件流。
FiLeOutputStream(FiLe fiLe, boolean append) 创建一个向指定FiLe对象表示的文件中写入数据的文件输出流。参数:
string name ,File file:写入数据的目的地boolean
append :追加写开关
- true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据
- false:创建一个新文件,覆盖源文件
写换行: 写换行符号
windows : \r\n
注: 实测win10下,只写\r或者\n也都可以换行
Linux :/n
mac :/r
字节输入流
java.io.InputStream:字节输入流
此抽象类是表示字节输入流的所有类的超类。定义了所有子类共性的方法:
int read()从输入流中读取数据的下一个字节。
int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组中。
void close()关闭此输入流并释放与该流关联的所有系统资源。
文件字节输入流
java.io.FileInputStream extends Inputstream
FileInputStream:文件字节输入流
作用:把硬盘文件中的数据,读取到内存中使用
构造方法:
FiLeInputstream( String name)
FileInputstream( File file)
参数:读取文件的数据源
string name:文件的路径
File file:文件
字节输入流一次读取多个字节的方法:
int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组中。明确两件事情:
- 方法的参数byte[ ]的作用? 起到缓冲作用,存储每次读取到的多个字节
数组的长度一把定义为1024(1KB)或者1024的整数倍 - 方法的返回值int是什么? 每次读取的有效字节个数
String类的构造方法
String ( byte[] bytes) : 把字节数组转换为字符串
String(byte[ ] bytes,int offset, int length)) 把字节数组的一部分转换为字符串
offset :数组的开始索引
length:转换的字节个数
字符输入流
java.io.Reader:字符输入流
是字符输入流的最顶层的父类,定义了一些共性的成员方法,是一个抽象类
共性的成员方法:
int read() 读取单个字符并返回。
int read(char[] cbuf) 一次读取多个字符,将字符读入数组。void close()关闭该流并释放与之关联的所有资源。
文件字符输入流
java.io.FileReader extends InputStreamReader extends ReaderFiLeReader:文件字符输入流
作用:把硬盘文件中的数据以字符的方式读取到内存中
构造方法:
FileReader( string fiLeName)FiLeReader( File file)
参数:读取文件的数据源
string fiLeName:文件的路径
FiLe file:一个文件
对比字符流和字节流:
try {
FileInputStream fis = new FileInputStream("Day06\\src\\a.txt");
int read = 0;
while ((read = fis.read())!=-1){
System.out.print(read+" ");
}
// int read = fis.read(); //返回的是ASCII码值
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println();
try {
FileReader fileReader = new FileReader("Day06\\src\\a.txt");
int read = 0;
while ((read = fileReader.read())!=-1){
System.out.print(read+" ");
}
// int read = fis.read(); //返回的是ASCII码值
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
文件a.txt
Hello World!
ABC你好
结果截图:
可以看出使用字符流时,是一个字符一个字符读取的。而用字节流时,是一个字节一个字节读取的,中文”你好“就用了六个字节。
字符输出流
java.io.writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类共性的成员方法:
- void write(int c)写入单个字符。
- void write(char[]cbuf)写入字符数组。
- abstractvoid 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()关闭此流,但要先刷新它。
文件字符输出流
java.io.Filelriter extends outputstreamwriter extends writerFiLewriter:文件字符输出流
作用:把内存中字符数据写入到文件中
构造方法:
FiLewriter(File fiLe) 根据给定的 FiLe 对象构造一个 Filewriter对象。FiLewriter(String fiLeName) 根据给定的文件名构造一个FiLewriter 对象。
参数:写入数据的目的地
String fiLeName:文件的路径
File file:是一个文件
构造方法的作用:
- 会创建一个FiLewriter对象
- 会根据构造方法中传递的文件/文件的路径,创建文件
- 会把FiLewriter对象指向创建好的文件
注意:字符输出流与字节输出流不同,字节输出流不需要flush刷新就可以输出,而字符输出流必须要通过刷新才会输出到文件目的地。
try {
FileWriter fileWriter = new FileWriter("Day06\\src\\b.txt");
fileWriter.write("Hello World!!");
} catch (IOException e) {
e.printStackTrace();
}
尝试使用此代码进行创建文件并写入数据,会发现没有刷新,文件里没有任何数据。这段代码刻意没有close,因为close默认会刷新一次。
缓冲输入输出流
java.io.Bufferedoutputstream extends outputstreamBufferedoutputstream:字节缓冲输出流
继承自父类的共性成员方法:
- 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):将指定的字节输出流。
构造方法:
- BufferedoutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
- BufferedoutputStream(OutputStream out,int size)创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流
参数:
outputstream out:字节输出流
我们可以传递FiLeOutputStream , 缓冲流会给FileOutputStream增加一个缓冲区,提高FiLeOutputStream的写入效率
int size:指定缓冲流内部缓冲区的大小,不指定黑默认
使用步骤(重点)
- 创建Fileoutputstream对象,构造方法中绑定要输出的目的地
- 创建BufferedoutputStream对象,杓造方法中传递FileOutputStream对象对象,提高FiLeOutputStream对象效率
- 使用Bufferedoutputstream对象中的方法write,把数据写入到内部缓冲区中
- 使用BufferedoutputStream对象中的方法fLush,把内部缓冲区中的数据,刷新到文件中5.释放资源(会先调用flush方法刷新数据,第4倍部可以省略
try {
FileOutputStream fos = new FileOutputStream("Day06\\src\\c.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write("Hello World!!".getBytes());
bos.close(); //使用bos close时默认也会将fos关闭
} catch (IOException e) {
e.printStackTrace();
}
java.io.BufferedInputstream extends InputstreamBufferedInputstream:字节缓冲输入流
继承自父类的成员方法:
int read()从输入流中读取数据的下一个字节。
int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b 中。void close()关闭此输入流并释放与该流关联的所有系统资源。
构造方法:
BufferedInputStream(InputStream in)创建一个BufferedInputStream并保存其参数,即输入流in,以便将来使用。
BufferedInputStream(InputStream in, int size)创建具有指定缓冲区大小的BufferedInputStream并保存其参数,即输入流
参数:
Inputstream in:字节输入流
我们可以传递FiLeInputStream ,缓冲流会给FileInputStream增加一个缓冲区,提高FileInputStream的读取效率int size:指定缓冲流内部缓冲区的大小,不指定默认
使用步骤(重点)∶
- 创建FileInputstream对象,构造方法中绑定要读取的数据源
- 创建BufferedInputStream对象,构造方法中传递FiLeInputStream对象,提高FileInputStream对象的读取效率
- 使用BufferedInputstream对象中的方法read,读取文件
- 释放资源
try {
FileInputStream fis = new FileInputStream("Day06\\src\\c.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int read = 0;
while((read = bis.read())!=-1){
System.out.print((char) read);
}
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
与不使用缓冲流的效率对比:
long b = System.currentTimeMillis();
try {
FileInputStream fis = new FileInputStream("Day06\\src\\c.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int read = 0;
while((read = bis.read())!=-1){
// System.out.print((char) read);
}
long e = System.currentTimeMillis();
bis.close();
System.out.println("BufferedInputStream:"+ (e-b));
} catch (IOException e) {
e.printStackTrace();
}
b = System.currentTimeMillis();
try {
FileInputStream fis = new FileInputStream("Day06\\src\\c.txt");
int read = 0;
while((read = fis.read())!=-1){
// System.out.print((char) read);
}
long e = System.currentTimeMillis();
fis.close();
System.out.println("FileInputStream:"+(e-b));
} catch (IOException e) {
e.printStackTrace();
}
可以看出使用Buffer缓存区,效率提升巨大
c.txt
java.io.Bufferedwriter extends writerBufferedwriter:字符缓冲输出流
继承自父类的共性成员方法:
- void write( int c)写入单个字符。
- void write( char[] cbuf)写入字符数组。
- abstract void write(char[ ] cbuf,int off, int len)写入字符数组的某一部分, of数组的开始索引,Len写的字符个数。
- void write(String str)写入字符串。
- void write(String str,int off,int len)写入字符串的某一部分, off字符串的开始索引,Len写的字符个数。
- void flush()刷新该流的缓冲。
- void close()关闭此流,但要先刷新它。
构造方法:
Bufferedwriter(writer out)创建一个使用黑认大小输出缓冲区的缓冲字符输出流。
Bufferedwriter(writer out, int sz)创建一个使用给定大小输出缓冲区的新缓冲字符输出流。参数:
writer out:字符输出流
我们可以传递
FiLewriter,缓冲流会给FiLewriter增加一个缓冲区,提高FiLewriter的写入效率
int sz:指定缓冲区的大小,不写默认大小
特有的成员方法:
void newLine( )写入一个行分隔符。会根据不同的操作系统,获取不同的行分隔符换行:换行符号
vindows : \r\n
linux : /n
mac : /r使用步骤:
- 创建字符缓冲输出流对象,构造方法中传递字符输出流
- 调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中
- 调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中
- 释放资源
java.io.BufferedReader extends Reader
继承自父类的共性成员方法:
int read()读取单个字符并返回。
int read( char[ ] cbuf)一次读取多个字符,将字符读入数组。
void close()关闭该流并释放与之关联的所有资源。
构造方法:
BufferedReader(Reader in)创建一个使用黑认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz)创建一个使用指定大小输入缓冲区的缓冲字符输入流。
参数:
Reader in:字符输入流
我们可以传递FiLeReader ,缓冲流会给FiLeReader增加一个缓冲区,提高FiLeReader的读取效率
特有的成员方法:
string readLine()读取一个文本行。读取一行数据
行的终止符号: 通过下列字符之一即可认为某行已终止:换行(‘\n’)、回车(‘\r’)或回车后直接跟着换行(\r\n)。
返回值:
包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回nul
使用缓冲字符流复制文件
try {
BufferedReader br = new BufferedReader(new FileReader("Day06\\src\\c.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("Day06\\src\\c_copy.txt"));
String line;
while((line = br.readLine())!=null){
bw.write(line);
bw.newLine();
}
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}