javaI/O——轉換流 and 檔案拷貝
阿新 • • 發佈:2019-01-08
一、轉換流
1.轉換流的基本使用
我們前面已經學習了兩種資料流了:位元組流和字元流。其實這兩種流是可以相互轉換的。
OutputStreamWriter:將位元組輸出流變為字元輸出流;
InputStreamReader:將位元組輸入流變為字元輸入流;
下面我們來看看這兩個類的構造方法:
輸出流:
a.public class OutputStreamWriter extends Writer
b.public OutputStreamWriter(OutputStream in)
傳的是位元組流的物件
輸入流:
a.public class InputStreamReader extends Reader
b.public InputSreamreader(InputStream in)
eg:
//字元流與位元組流的相互轉化 public class TestOutputStreamWriter { public static void main(String[] args) throws Exception { //位元組流->字元流 編碼 //字元流->位元組流 解碼 //1.建立字元流: File srcFile = Paths.get("E:", "learn", "javaio", "a1").toFile();//準備檔案 File destFile = Paths.get("E:", "learn", "javaio", "a3").toFile();//讀的檔案 try( FileInputStream inputStream = new FileInputStream(srcFile);//準備輸入流物件 FileOutputStream outputStream = new FileOutputStream(destFile);//準備輸出流物件 InputStreamReader reader = new InputStreamReader(inputStream);//將位元組流物件傳到方法中-》轉化為字元流 //下面就可以用reader按照字元流讀了 OutputStreamWriter writer = new OutputStreamWriter(outputStream)//將位元組輸出流作為引數傳遞-》最後一個省略分號 ) { //按照字元讀取 char[] buff = new char[1024];//不要開闢太大,這個空間是會在記憶體開闢的 int len = -1; //在讀取內容的時候,將內容放進字元陣列中,同時返回讀取的個數,當沒有資料了但還在讀,這個時候就返回-1,所以用-1來判斷是否還在讀取資料 while ((len = reader.read(buff)) != -1) { writer.write(buff,0,len); } } catch (Exception e) { } } }
綜合案例(重要)——檔案拷貝:
方法一:在程式中開闢一個數組,該陣列長度為檔案長度,將所有資料一次性讀取到該陣列進行輸出儲存
////檔案拷貝方法1: //public class CopyFile { // public static void main(String[] args) { // // 原檔案--》目標檔案 // try{ // String src = args[0]; // String dest = args[1]; // cp(src,dest); // }catch(ArrayIndexOutOfBoundsException e){ // System.out.println("引數不符合要求:srcFilePath destFilePath"); // } // } // // //拷貝檔案的整個方法 // public static void cp(String srcFilePath, String destFilePath) {//引數是:原檔案,目標檔案 // checkArguments(srcFilePath); // checkArguments(destFilePath); // checkFileExists(srcFilePath);//原檔案要存在 // checkFileNotExists(destFilePath);//目標檔案要不存在 // File srcFile=Paths.get(srcFilePath).toFile(); // File destFile=Paths.get(destFilePath).toFile(); // //拷貝 // copy(srcFile,destFile); // // } // // //拷貝的方法 // public static void copy(File srcFile,File destFile){ // try(FileInputStream in=new FileInputStream(srcFile); // FileOutputStream out=new FileOutputStream(destFile) // ){ // //增強版 帶緩衝區 // byte[] buff=new byte[1024]; // int len; // while((len=in.read(buff))!=-1){ // out.write(buff,0,len); // } // }catch (Exception e){ // System.out.println(e.getMessage()); // } // } // // //1.檢查引數 // private static void checkArguments(String args) { // if (args == null || args.isEmpty()) { // throw new IllegalArgumentException("引數不能為空"); // } // } // // //2.檢查檔案是否存在並且這個檔案是普通檔案 // private static void checkFileExists(String filePath) { // Path path = new Paths.get(filePath); // File file = path.toFile(); // if (!(file.exists() && file.isFile())) { // throw IllegalArgumentException(filePath + "not exsits"); // } // } // // //3.只是檢查這個檔案是否存在 // private static void checkFileNotExists(String filePath) { // Path path = new Paths.get(filePath); // File file = path.toFile(); // if ((file.exists())) { // throw IllegalArgumentException(filePath + "exsits"); // } // } //}
方法二:採用邊讀編寫的方式完成
//檔案拷貝方法2:
public class CopyFile{
//檔案複製
public static void copy(String srcFilePath,String destFilePath){
//1.判斷路徑是否為空(引數檢驗)
if(srcFilePath==null||srcFilePath.isEmpty()){
throw new IllegalArgumentException("srcFilePath must not null");
}
if(destFilePath == null||destFilePath.isEmpty()){
throw new IllegalArgumentException("destFilePath must not null");
}
//檔案校驗以及準備工作
File srcFile=Paths.get(srcFilePath).toFile();
File destFile=Paths.get(destFilePath).toFile();
//2.原檔案不存在或者為目錄
if(!srcFile.exists()||!srcFile.isFile()){
throw new IllegalArgumentException("srcFilePath file not exists or not file");
}
//3.判斷目標檔案的目錄是否存在。如果不存在並且不能建立那檔案不可以拷貝
//我們的輸出流只能夠建立檔案但是不能建立目錄,所以前提的保證這個目錄是存在的
File parentFile=destFile.getParentFile();
if(!parentFile.exists()){
if(!parentFile.mkdirs()){
throw new RuntimeException("can't create"+parentFile.getAbsolutePath()+"directory");
}
}
//開始複製
try(
FileInputStream in=new FileInputStream(srcFile);
FileOutputStream out=new FileOutputStream(destFile)
){
//以後在讀資料的時候我們都使用緩衝的方法
//此外注意:緩衝區不要取太大,一般在1k的整數倍就可以了
byte[] buff=new byte[1024];
int len=-1;
while((len=in.read(buff))!=-1){//->讀
out.write(buff,0,len);//->寫
}
}catch (IOException e){
e.getMessage();
}
}
public static void main(String[] args) {
String src="E:\\learn\\javaio\\a1";
String dest="E:\\learn\\javaio\\tashuo\\t1.exe";
//獲取當前時間戳
long start = System.currentTimeMillis();
copy(src,dest);
long end=System.currentTimeMillis();
System.out.println((end-start)/1000+" s");
}
}