Java的File.separator
一、File類
在Windows下的路徑分隔符(\)和在Linux下的路徑分隔符(/)是不一樣的,當直接使用絕對路徑時,跨平臺會報No Such file or diretory異常。
File中還有幾個與separator類似的靜態常量,與系統有關,在編程中應盡量使用。
ps:File file = new File("G:"+ File.separator +"demo.txt");
File類是java.io包中唯一一個與文件本身操作有關的類,文件本身操作是指文件的創建、刪除、重命名等
.構造方法:public File(String pathName),傳入完整的路徑,WEB開發此方式比較好用。
.構造方法:public File(File parent,String child),傳入父路徑和子路經。
基本的文件操作:
.創建新文件:public boolean createNewFile() throws IOException;
.刪除文件:public boolean delete();
.判斷文件是否存在:public boolean exists();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import java.io.File;
import java.io.IOException;
public class TestFile {
public static void main(String [] args) throws IOException{
File file = new File( "G:\\demo.txt" );
System.out.println( "file:" +file);
if (file.exists()){
file.delete();
System.out.println( "執行了刪除文件!" );
} else {
file.createNewFile();
System.out.println( "執行了創建文件" );
}
}
}
|
如果進行文件創建時有目錄,則需要先創建目錄之後才可以創建文件。
.找到父路徑:public File getParentFile();
.創建目錄:(1)public boolean mkdirs();既可以在不存在的目錄中創建文件夾又可以創建多級目錄(個人推薦使用此方法)
(2)public boolean mkdir();只能在已近存在的目錄中創建文件夾
import java.io.File; import java.io.IOException; public class TestFile { public static void main(String [] args) throws IOException{ File file = new File("G:"+ File.separator +"Test"+ File.separator +"TestFile"+ File.separator +"demo.txt"); if(!file.getParentFile().exists()){//文件不存在 file.getParentFile().mkdirs(); System.out.println("執行了創建多級目錄"); } if(file.exists()){//文件存在 file.delete(); System.out.println("執行了刪除文件!"); }else{ file.createNewFile(); System.out.println("執行了創建文件"); } } }
除了上述基本的文件和文件夾的操作之外,還提供了一些取得文件信息的方法:
.判斷路徑是否是文件:public boolean isFile();
.判斷路徑是否是文件夾:public boolean isDirectory();
.最後一次修改時間:public long lastModified();
.取得文件大小:public long length();
.修改文件名稱:public boolean renameTo(File dest);
import java.io.File; import java.math.BigDecimal; import java.text.SimpleDateFormat; public class TestFileOne { public static void main(String [] args){ File file = new File("G:"+ File.separator +"Test"+ File.separator +"TestFile"+ File.separator +"1.jpg"); if(file.exists()){ System.out.println(file.isDirectory()? "是文件夾" : "不是文件夾"); System.out.println(file.isFile() ? "是文件" : "不是文件"); System.out.println("最後修改時間:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified())); System.out.println("文件大小:" + new BigDecimal((file.length() / (double) 1024 / 1024)) .divide(new BigDecimal(1), 2,BigDecimal.ROUND_HALF_UP) + "M"); if(file.renameTo(new File("G:"+ File.separator +"Test"+ File.separator +"TestFile"+ File.separator +"hello.jpg"))){ System.out.println("重命名成功"); }else{ System.out.println("重命名失敗"); } } } }
列出指定文件夾中的所有內容:
public File [] listFiles();
import java.io.File; public class TestFileTwo { public static void main(String [] args){ File file = new File("G:" + File.separator + "Test"); if(file.exists() && file.isDirectory()){ File [] list = file.listFiles(); for(int i = 0; i < list.length; i ++){ System.out.println("files:"+list[i]); } } } }
列出指定目錄中的所有文件(包含所有子目錄中的文件),遞歸調用
import java.io.File; public class TestFileThree { public static void main(String [] args){ File file = new File("G:" + File.separator + "Test"); print(file); } public static void print(File file){ if(file.exists() && file.isDirectory()){ File [] files = file.listFiles(); if(files.length > 0 && files != null){ for(int i = 0; i < files.length; i++){ print(files[i]);//遞歸調用 } } } System.out.println(file); } }
二、字節流與字符流
使用File類只能進行文件本身的操作,但是與內容的操作無關。如果想進行文件內容操作可以使用一下兩組流:
.字節流InputStream OutputStream
.字符流reader writer
不管使用哪種流,基本的操作流程是一樣的,以文件操作為例:
.確定操作文件的路徑
.通過字節流或字符流的子類為字節流和字符流類對象實例化
.進行流入、流出操作
.關閉流,流屬於資源操作,資源操作完成一定要關閉
1、字節輸入流:OutputStream
java.io.OutputStream是可以進行字節數據(byte)的輸出
OutputStream類中存在三個write()方法:
·輸出單個字節:public void write(int b);
·輸出全部字節:public void write(byte [] b);
·輸出部分字節:public void write(byte [] b,int off,int len);
OutputStream是一個抽象類,所以可以使用子類對其進行實例化。對文件操作,可以使用FileOutputStream,這個類有兩個常用的構造方法:
public FileOutputStream(File file) throws FileNotFoundException,覆蓋;
public FileOutputStream(File file, boolean append) throws FileNotFoundException,追加;
對文件進行覆蓋的輸出操作:
package com.java.io; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class TestFile { public static void main(String [] args) throws IOException{ File file = new File("G:" + File.separator + "Test" + File.separator + "demo.txt"); if(!file.getParentFile().exists()){ file.getParentFile().mkdirs(); } //通過OutputStream的子類對象為父類對象實例化 OutputStream output = new FileOutputStream(file); //要輸出的數據 String msg = "Hello world."; //將字符串轉換為字節數組 byte [] data = msg.getBytes(); //輸出字節數組 output.write(data); output.flush(); //關閉 output.close(); } }
不管執行幾次,都是對當前文件的覆蓋。如果不想覆蓋,可以使用追加的方式創建FileOutputStream類對象
.追加內容:OutputStream output = new FileOutputStream(file, true);
單個字節:
package com.java.io; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class TestFile { public static void main(String [] args) throws IOException{ File file = new File("G:" + File.separator + "Test" + File.separator + "demo.txt"); if(!file.getParentFile().exists()){ file.getParentFile().mkdirs(); } //通過OutputStream的子類對象為父類對象實例化 OutputStream output = new FileOutputStream(file); //要輸出的數據 String msg = "Hello world.\r\n"; //將字符串轉換為字節數組 byte [] data = msg.getBytes(); //輸出字節數組 for(int i = 0; i < data.length; i++){ output.write(data[i]); } //關閉 output.close(); } }
2、字節輸入流:InputStream
在InputStream類中定義有三個read()方法:
·讀取單個字節:public int read() throws IOException;
每次使用read()操作將讀取一個字節數據,此時返回的是數據,如果數據已讀完,則int返回-1
.讀取內容到字節數組:public int read(byte [] b) throws IOException();
將內容讀取到字節數組中,返回讀取的個數,如果讀取完畢,則返回-1
.讀取內容到部分字節數組:public int read(byte [] b,int off,int len) throws IOException();
將指定長度的內容讀取到字節數組中,返回讀取個數,如果讀取完畢,則返回-1
InputStream是抽象類,所以可以使用它的子類對其進行實例化。使用FileInputStream子類完成,其構造方法:
public FileInputStream(File file) throws FileNotFoundException;
使用InputStream讀取數據
package com.java.io; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; public class TestFileOne { public static void main(String[] args) throws Exception { File file = new File("G:"+File.separator+"Test"+File.separator+"demo.txt"); if(file.exists()){//文件存在 InputStream input = new FileInputStream(file); byte [] data = new byte[1024];//此數組用於接受全部輸入數據 int len = input.read(data);//將數據保存到數組中 System.out.println(""+new String(data, 0, len)); input.close(); } } }
實際開發中使用while循環讀取
package com.java.io; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; public class TestFileOne { public static void main(String[] args) throws Exception { File file = new File("G:"+File.separator+"Test"+File.separator+"demo.txt"); if(file.exists()){//文件存在 InputStream input = new FileInputStream(file); byte [] data = new byte[1024];//此數組用於接受全部輸入數據 int temp = 0;//定義每次讀取進來的數據 int foot = 0;//定義數組角標 //(temp = input.read()) != -1 判斷temp是否等於-1,如果不是則繼續讀 while((temp = input.read()) != -1){ data[foot++] = (byte) temp; } input.close(); //打印 System.out.println(new String(data, 0, foot)); } } }
3、字符輸出流:Writer
字節輸出流和字符輸出流的區別:字節輸出流是以byte類型為主,而字符輸出流是以char為主,並且支持String的直接操作
Writer類中的操作方法:
·輸出字符串:public void write(String str) throws IOException;
·輸出字節數組:public void write(char [] cbuf) throws IOException;
但Writer是一個抽象類,如果使用它進行文件操作必須使用FileWriter子類
package com.java.io; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class TestFileWriter { public static void main(String [] args) throws IOException{ File file = new File("G:"+File.separator+"Test"+File.separator+"fileWrite.txt"); if(!file.getParentFile().exists()){ file.getParentFile().mkdirs(); } Writer out = new FileWriter(file); String msg = "Hello world."; out.write(msg); out.close(); } }
4、字符輸入流
Reader是負責字符數據讀取的,使用read()方法實現讀取,但沒有直接返回String類型的讀取操作
·讀取數據:public int read(char [] cbuf) throws IOException;
package com.java.io; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class TestFileWriterOne { public static void main(String [] args) throws IOException{ File file = new File("G:"+File.separator+"Test"+File.separator+"fileWrite.txt"); if(file.exists()){ Reader in = new FileReader(file); char [] data = new char[1024]; int len = in.read(data); in.close(); System.out.println(new String(data,0,len)); } } }
兩種讀取操作本質上區別不打,只是字符操作的是String/char,而字節操作的是byte;
5、字節流和字符流的區別
·字符流:當程序進行中文處理時,字符流是最方便;
·字節流:當程序處理二進制數據(圖片、音樂、電影)或網絡數據傳輸,或者保存到磁盤數據一定是字節;
除以上區別之外,字節流在操作時直接與操作終端進行交互,而字符流需要經過緩沖區的處理後才可以進行操作,以OutputStream和Writer兩個類輸出文件為例,如果OutputStream輸出的最後可以不關閉輸出流,但是如果是Writer類輸出的如果沒有關閉,那麽保存在緩沖區之中的數據將無法輸出,或者強制刷新緩沖區。
package com.java.io; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class TestWriter { public static void main(String [] args) throws IOException{ File file = new File("G:"+File.separator+"Test"+File.separator+"fileWrites.txt"); if(!file.getParentFile().exists()){ file.getParentFile().mkdirs(); } Writer out = new FileWriter(file); String msg = "Hello world,I am a programer."; out.write(msg); out.flush(); //out.close(); } }
所謂緩沖區就是一塊內存,當數據讀取進來之後會先進入內存區域之中進行處理,所以才可以更好的處理中文
三、轉換流
既然存在字節和字符兩種操作流,那麽兩種操作流之間是可以進行相互轉換的,主要使用兩個類: InputStreamReader、OutputStreamWriter
InputStreamReader是Reader的子類,所以InputStreamReader類對象可以自動轉型為Reader類實例。
OutputStreamWriter是Writer的子類,所以OutputStreamWriter類對象可以自動轉型為Writer類實例。
Java的File.separator