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();