JavaIO-BIO(阻塞式IO)-基于抽象类
学习IO需要核心掌握五个类(File,OutputStream,InputStream,Reader,Writer) 及一个接口(Serializable)
**
1.File文件操作类——既可以描述具体文件也可以描述文件夹
**
在java.io包之中,File类是唯一一个与文件本身操作(创建、删除、取得信息…)有关的程序类
文件操作三步走:
1.取得File对象;2.判断父路径是否存在,不存在就创建多级父路径;3.判断文件是否存在,不存在就创建文件
1.1File类使用
java.io.File类是一个普通类,直接产生实例化对象即可。如果要实例化对象则需要使用到两个构造方法:
public File(String pathname);
public File(String parent,String child);
根据网络产生File对象:public File(URI uri)
如果想要进行文件的基本操作,可以使用File类的如下方法:
I.创建一个新文件
public boolean createNewFile() throws IOException
public class TestCreateFile {
//文件创建
public static void main(String[] args) {
//定义要操作的文件路径
File file =new File("D:\\JavaSE code\\test\\java7.java");
boolean rs= false;
try {
rs = file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
if(rs){
System.out.println("成功");
}else{
System.out.println("失败");
}
}
}
II.编写文件的基本操作
1)判断文件是否存在
public boolean exists();
2)删除文件
public boolean delete();
范例:如果文件不存在则进行创建;存在就删除
package javaSE.bit.file;
import java.io.File;
import java.io.IOException;
/**
* 编写文件的基本操作
* 如果文件不存在就进行创建,存在就删除
*/
public class FileOperations {
public static void main(String[] args) {
// File file=new File("D:\\JavaSE code\\test\\java7.java");
File file=new File("D:"+File.separator+"JavaSE code"+File.separator
+"test"+File.separator+"java7.java");
// exists()判断文件是否存在
// delete()删除文件
if(file.exists()){
boolean rs=file.delete();
System.out.println("delete 的结果:"+rs);
}else{
try {
boolean rs=file.createNewFile();
System.out.println("createNewFile 的结果:"+rs);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
科普:操作系统不同文件的表示不同
- Windows:文件名不区分大小写;目录分隔符为(反斜杠) 会与转移符连用"\";路径分隔符(;)
- Linux:文件名区分大小写;目录分隔符为/(正斜杠);路径分隔符(:)
III.分隔符
separator由不同操作系统下的JVM来决定到底是哪个分隔符(杠杠\还是/):
例如:
File file=new File("D:\\JavaSE code\\test\\java7.java");
如果这行代码存在于不同的操作系统,就会存在问题(分隔符在不同系统是不一样的),因此在使用分隔符的时候都会采用File类的一个常量"public static final String separator"来描述:
利用separator后可以跨平台使用:
File file=new File("D:"+File.separator+"JavaSE code"+File.separator
+"test"+File.separator+"java7.java");
1.2目录操作
File类中关于目录有如下的方法:
I.取得父路径的File对象:public File getParentFile();
取得父路径的目录:public String getParent();
II.创建目录(无论有多少级目录,都会创建)
1)public boolean mkdirs();
2)File对象中的mkdir和mkdirs区别:
mkdir 创建当前目录,如果父目录不存在则创建失败
mkdirs 创建当前目录,如果父目录不存在一并创建;通常创建目录时,优先使用mkdirs
1.3文件信息
在File类中提供有一系列取得文件信息的操作:
1)判断路径是否是文件:public boolean isFile();
2)判断路径是否是目录:public boolean isDirectory();
3)取得文件大小(字节):public long length();
4)最后一次修改日期:public long lastMpdified();
5)当满足 if(file.exists()&&file.isFile) 表示文件确实存在
范例:取得文件信息
package javaSE.bit.file;
import java.io.File;
import java.util.Date;
/**
* File类中提供的取得文件信息的操作
* @author mayanni
* @date 2019-04-20 15:34
*/
public class GetFileInfo {
public static void main(String[] args) {
File file=new File("D:"+File.separator+"JavaSE code"+File.separator
+"test"+File.separator+"java7.java");
System.out.println("文件是否存在:"+file.exists());
System.out.println("文件对象是否表示文件:"+file.isFile());
System.out.println("文件对象是否表示目录:"+file.isDirectory());
//Date date=new Date(file.lastModified());
System.out.println("最近修改时间:"+new Date(file.lastModified()));
System.out.println("文件大小(字节):"+file.length());
}
}
6)列出一个目录的全部组成:public File[] listFiles()
1.4综合案例——目录列表
File提供由listFile()方法,但是这个方法本身只能够列出本目录中的第一级信息。如果要列出目录中所有级的信息,必须由自己来处理。这种操作必须通过递归的模式来完成
范例:递归打印当前目录下所有级层的文件信息
public class TestListFiles {
public static void main(String[] args) {
//1.取得file对象
File file=new File("D:"+File.separator+"JavaSE code"+File.separator +"test");
//将IO操作放在子线程中进行
new Thread(()->{
long start=System.currentTimeMillis();
listAllFiles(file);
long end=System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}).start();
System.out.println("main线程结束");
}
public static void listAllFiles(File file){
if(file.isFile()){
System.out.println(file);
}else{
if(file.exists()&&file.isDirectory()){
File[] files=file.listFiles();
for (File file1:files){
listAllFiles(file1);
}
}
}
}
}
线程阻塞问题:
现在所有的代码都是在main线程下完成的,如果listAllFile()方法没有完成,n那么对于main后续的执行将无法完成。这种耗时的操作让主线程出现了阻塞,而导致后续代码无法正常执行完毕。如果不想让阻塞产生,最好再产生一个新的线程进行处理。
范例:新增子线程进行耗时操作
new Thread(()->{
long start=System.currentTimeMillis();
listAllFiles(file);
long end=System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}).start();