JAVA中的I/O流以及文件操作


一 JAVA語言中主要通過流來完成IO操作。

流:計算機的輸入輸出之間流動的數據序列,也是類的對象。java中的流方式就像是建立在數據交換源和目的之間的一條通信路徑。

數據源:計算機中的數據源是指可以提供數據的地方,包括鍵盤,磁盤文件,網絡接口等。

輸入流:從程序外部傳向程序的流。輸入流只能從中讀數據。

輸出流: 從程序傳到外部的流。輸出流只能向其寫入數據。

所謂的輸入和輸出是以程序為中心的,數據流向程序即輸入流,數據從程序中流出即輸出流。

二 字節流

字節流是以字節為傳輸單位的數據讀寫形式,用於直接讀取二進制數據,如圖像和聲音文件等。

InputStream和OutputStream分別為面向字節的輸入流類的父類和輸出流類的父類。InputStream和OutputStream都是抽象類。

FileInputStream和FileOutputStream是文件流類,他們是InputStream和OutputStream的子類。

FileInputStream類的一般用法是:先創建一個FileInputStream對象關聯到要讀取的文件,然后調用read方法讀取字節數據到程序中,再進行其他處理。因為read方法是按字節的讀入的,所以漢字被讀入時會出現亂碼。

FileOutputStream類的一般用法是:先創建一個FileOutputStream對象關聯到要寫入的文件,然后調用write方法將字節數據寫到程序中。如果進行寫操作的文件不存在,則自動創建該文件,但是如果文件所在的路徑也不存在,則運行時會報錯。

例如 FileOutputStream fos = new FileOutputStream("D:\\test.txt");是不會報錯的,

      FileOutputStream fos = new FileOutputStream("D:\\tmp\\test.txt");如果之前在D盤中沒有tmp這個文件夾,那么此時運行這條語句會報錯。

 

代碼如下

 1 package 文件操作_FileInputStream和FileOutputStream;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileNotFoundException;
 5 import java.io.FileOutputStream;
 6 import java.io.IOException;
 7 
 8 public class FileDemo {
 9     public static void main(String[] args) {
10         try {
11             FileInputStream fis = new FileInputStream("D:\\test.txt");
12             int  ch = fis.read();
13             while (ch != -1) {
14                 System.out.print((char) ch);
15                 ch = fis.read();
16             }
17 //            byte[] buffer = new byte[8];
18 //            fis.read(buffer);
19 //            for (int i = 0; i < buffer.length; i++) {
20 //                System.out.print((char) buffer[i]);
21 //            }
22             FileOutputStream fos = new FileOutputStream("D:\\test1.txt");
23             byte[] b = {'a', 'c', 'd', 'e', 'x'};
24             fos.write(b);
25             fis.close();
26             fos.close();
27         } catch (FileNotFoundException e) {
28             // TODO Auto-generated catch block
29             e.printStackTrace();
30         } catch (IOException e) {
31             e.printStackTrace();
32         }
33     }
34     
35 
36 }
View Code

 

緩存流 BufferedInputStream 和 BufferedOutputStream

使用緩存流可以提高大文件的讀寫效率。例如從文件讀入數據時,每次從輸入流中讀取較大的數據量存入內存緩沖區,具體的讀操作針對該緩沖區進行;執行緩沖輸出時,每次將輸出流中的數據寫入到內存緩沖區,知道緩沖區寫滿,才將數據寫入到最終的介質中。

使用緩存流的缺點:當計算機突然關閉時,可能會丟失數據。通過清空緩沖區的數據可以減少這種情況的發生,使用flush()方法即可。

代碼如下

 1 package 文件操作_BufferedInputStream;
 2 
 3 import java.io.BufferedInputStream;
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.IOException;
 7 
 8 public class BufferDemo {
 9     public static void main(String[] args) {
10         try {
11             FileInputStream fis = new FileInputStream("D:\\test.txt");
12             BufferedInputStream bis = new BufferedInputStream(fis); //默認的輸入緩沖區是2048B
13             int ch = bis.read();
14             while (ch != -1) {
15                 System.out.print((char)ch);
16                 ch = bis.read();
17             }
18                     
19         } catch (FileNotFoundException e) {
20             // TODO Auto-generated catch block
21             e.printStackTrace();
22         } catch (IOException e) {
23             e.printStackTrace();
24         }
25     }
26 
27 }
View Code

 

三 字符流

Reader 和 Writer類是所有字符流的父類。一次讀取或是寫入兩個字節,16位,即一個Unicode字符,因此可以使用字符流直接讀寫漢字內容。

BufferedReader 和 BufferedWriter類的用法示例

 1 package 文件操作_字符流_BufferedReader和BufferedWriter;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.BufferedWriter;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileReader;
 7 import java.io.FileWriter;
 8 import java.io.IOException;
 9 
10 public class BufferedDemo {
11     public static void main(String[] args) {
12         try {
13             FileReader fr = new FileReader("D:\\test.txt");
14             BufferedReader br = new BufferedReader(fr);
15             FileWriter fw = new FileWriter("D:\\test1.txt");
16             BufferedWriter bw = new BufferedWriter(fw);
17             String str = br.readLine();
18             while (str != null) {
19                 bw.write(str);
20                 bw.newLine();
21                 str = br.readLine();
22             }
23             br.close();
24             bw.close();
25         } catch (FileNotFoundException e) {
26             // TODO Auto-generated catch block
27             e.printStackTrace();
28         } catch (IOException e) {
29             e.printStackTrace();
30         }
31     }
32 
33 }
View Code

 

四 File文件類

File aa = new File(aaName); 這里的aa可以指向文件,也可以指向文件夾


在進行文件的操作時,若操作的對象是文件,那么在進行文件的創建,刪除,復制之前,

(1)需要判斷文件是否存在,
(2)以及File所指向的對象是一個文件還是一個文件夾(目錄)
(3)該文件所在的文件夾是否存在,file.getParentFile().exists()
 (4)若文件所在的文件夾不存在,需要建立其父文件夾,若未建立成功,返回false
       if (!file.getParentFile().mkdirs()) return false;

在對文件夾(目錄)進行操作時,

(1)首先判斷 dirName 是不是以文件分隔符 File.separator結尾,如果不是,

     則 dirName += File.separator;

(2)需要判斷 File dir = new File(dirName) 中的dir是不是存在以及指向的是不是一個文件夾 dir.exists() dir.isDirctory();
(3) 在對文件夾進行復制,刪除等操作時,一般會用到遞歸,因為文件夾里面有時候會存在子文件夾。

 

程序示例1 刪除指定目錄下的文件

 1 package 輸入輸出流_刪除指定目錄下的文件;
 2 
 3 import java.io.File;
 4 
 5 //delete()方法可以刪除文件和文件夾,當成功刪除文件或文件夾后,返回true  否則返回false
 6 //在使用delete()方法時,如果此路徑名表示一個文件夾(目錄),則此目錄必須為空才能刪除
 7 //(若要刪除文件夾,需要先刪除文件夾中的文件和文件夾,才能刪除該文件夾)
 8 public class FileDemo_05 {
 9     
10     public static boolean deleteFilesOrDir (String fileName) {//判斷將指定文件或文件夾刪除是否成功
11         File file = new File(fileName);
12         if (!file.exists()) {   //指定的文件或文件夾不存在,返回false
13             System.out.println("文件刪除失敗,因為文件" + fileName + "不存在");
14             return false;
15         } else {  //指定的文件或是文件夾存在
16             if (file.isFile()) {   //若file 是文件
17                 return FileDemo_05.deleteFiles(fileName);
18             } else {              //若file是文件夾
19                 return FileDemo_05.deleteDir(fileName);
20             }
21         }
22         
23     }
24     
25     public static boolean deleteFiles(String fileName) { //判斷刪除指定文件是否成功
26         File file = new File(fileName);
27         if ( file.exists() && file.isFile() ) {
28             if (file.delete()) {
29                 System.out.println("文件" + fileName + "刪除成功!");
30                 return true;
31             } else {
32                 System.out.println("文件" + fileName + "刪除失敗!");
33                 return false;
34             }
35         } else {
36             System.out.println("文件刪除失敗 : " + fileName + "文件不存在!");
37             return false;
38         }
39         
40     }
41     
42     public static boolean deleteDir(String dir) { //判斷刪除指定文件夾以及文件夾下的文件是否成功
43          if (!dir.endsWith(File.separator)) {
44              dir += File.separator;
45          }
46          File dirFile = new File(dir);
47          if (!dirFile.exists() || !dirFile.isDirectory()) {
48              System.out.println("文件夾刪除失敗!" + dir + "文件夾不存在");
49              return false;
50          }
51          boolean flag = true;
52          File[] files = dirFile.listFiles();
53          for (int i = 0; i < files.length; i++) {
54              if (files[i].isFile()) {            //刪除文件
55                  flag = FileDemo_05.deleteFiles(files[i].getAbsolutePath());
56                  if (!flag) {
57                      break;
58                  }
59              } else if (files[i].isDirectory()) {  //刪除子文件夾,此處為遞歸
60                  flag = FileDemo_05.deleteDir(files[i].getAbsolutePath());
61                  if (!flag) {
62                      break;
63                  }
64              } 
65          }
66          if (!flag) {
67              System.out.println("刪除文件夾失敗");
68          }
69          if (dirFile.delete()) {
70              System.out.println("文件夾" + dir + "刪除成功!");
71              return true;
72          } else {
73              return false;
74          }
75     }
76     
77     
78 
79 }
View Code

程序示例2 移動指定目錄下的文件,該程序用到了 程序示例1

  1 package 輸入輸出流_移動指定目錄下的文件;
  2 
  3 import java.io.File;
  4 
  5 public class FileDemo_06 {
  6     //英東某個指定的文件,但移動成功后不會覆蓋已存在的文件
  7     public static boolean moveA_File(String sourceFileName, String targetFileName) {
  8         return FileDemo_06.moveA_File(sourceFileName, targetFileName, false);
  9     }
 10     
 11     //移動某個指定的文件,但移動成功后可以根據isOverlay的值來決定是否覆蓋已存在的目標文件
 12     public static boolean moveA_File(String sourceFileName, String targetFileName,
 13                                         boolean isOverlay) {
 14         File sourceFile = new File(sourceFileName);
 15         if (!sourceFile.exists()) {
 16             System.out.println("文件" + sourceFileName + "不存在,移動失敗");
 17             return false;
 18         } else if (!sourceFile.isFile()) {
 19             System.out.println(sourceFileName + "不是文件,移動失敗");
 20             return false;
 21         }
 22         File targetFile = new File(targetFileName);
 23         if (targetFile.exists()) {
 24             if (isOverlay) {
 25                 System.out.println("目標文件已經存在,准備刪除它");
 26                 if (!FileDemo_05.deleteFilesOrDir(targetFileName)) {
 27                     System.out.println("文件移動失敗,文件" + targetFileName + "刪除失敗");
 28                     return false;
 29                 } 
 30             } else {
 31                 System.out.println("文件移動失敗,因為文件" + targetFileName + "已經存在");
 32                 return false;
 33             }
 34         } else {
 35             if (!targetFile.getParentFile().exists()) {
 36                 System.out.println("文件" + targetFile + "所在的目錄不存在,正在創建");
 37                 if (!targetFile.getParentFile().mkdirs()) {
 38                     System.out.println("移動文件失敗,因為創建文件坐在的文件夾失敗");
 39                     return false;
 40                 }
 41             }
 42         }
 43         
 44         //移動源文件至目標文件
 45         if (sourceFile.renameTo(targetFile)) {
 46             System.out.println("移動源文件" + sourceFileName + "到" + targetFileName 
 47                     + "成功" );
 48             return true;
 49         } else {
 50             System.out.println("移動源文件" + sourceFileName + "到" + targetFileName 
 51                     + "失敗" );
 52             return false;
 53         }
 54         
 55         
 56     }
 57     
 58     public static boolean moveDir(String sourceDirName, String targetDirName) {
 59         //默認為不覆蓋目標文件
 60         return FileDemo_06.moveDir(sourceDirName, targetDirName, false);
 61     }
 62     
 63     //移動某個指定的目錄,但移動成功后可以根據isOverlay的值來決定是否覆蓋當前已存在的目標目錄
 64     public static boolean moveDir(String sourceDirName, String targetDirName,
 65                                 boolean isOverlay) {
 66         //判斷原目錄是否存在
 67         File sourceDir = new File(sourceDirName);
 68         if (!sourceDir.exists()) {
 69             System.out.println("源目錄" + sourceDirName + "不存在,移動目錄失敗");
 70             return false;
 71         } else if (!sourceDir.isDirectory()) {
 72             System.out.println("移動目錄失敗," + sourceDirName + "不是目錄");
 73             return false;
 74         }
 75         //如果目標文件名不是以文件分割符結尾,自動添加文件分隔符
 76         if (!targetDirName.endsWith(File.separator)) {
 77             targetDirName += File.separator;
 78         }
 79         File targetDir = new File(targetDirName);
 80         //如果目標文件夾存在
 81         if (targetDir.exists()) {
 82             if (isOverlay) {
 83                 //允許刪除則刪除已存在的目標目錄
 84                 System.out.println("該目錄已經存在,准備刪除它");
 85                 if (!FileDemo_05.deleteFilesOrDir(targetDirName)) {
 86                     System.out.println("移動目錄失敗,因為目標目錄已經存在。   刪除目錄" + 
 87                         targetDirName + "失敗!"                        );
 88                 }
 89             } else {
 90                 System.out.println("移動目錄失敗:該目錄" + targetDirName + "已存在!");
 91                 return false;
 92             }
 93         } else {
 94             //創建目標目錄
 95             System.out.println("該目錄不存在,正在創建");
 96             if (!targetDir.mkdirs()) {
 97                 System.out.println("移動目錄失敗: 創建目標目錄失敗");
 98                 return false;
 99             }
100         }
101         boolean flag = true;
102         //移動原目錄下的文件和子目錄到目標目錄下
103         File[] files = sourceDir.listFiles();
104         for (int i = 0; i < files.length; i++) {
105             //移動子文件
106             if (files[i].isFile()) {
107                 flag = FileDemo_06.moveA_File(files[i].getAbsolutePath(),
108                         targetDirName + files[i].getName(), isOverlay);
109                 if (!flag) {
110                     break;
111                 }
112             } else if (files[i].isDirectory()) { //移動子目錄
113                 flag = FileDemo_06.moveDir(files[i].getAbsolutePath(),
114                         targetDirName + files[i].getName(), isOverlay);
115                 if (!flag) {
116                     break;
117                 }
118                 
119             }
120         }
121         
122         if (!flag) {
123             System.out.println("目錄" + sourceDirName + "移動到" + targetDirName + "失敗");
124             return false;
125         }
126         //刪除原目錄
127         if (FileDemo_05.deleteDir(sourceDirName)) {
128             System.out.println("目錄" + sourceDirName + "移動到" + targetDirName + "成功");
129             return true;
130         } else {
131             System.out.println("目錄" + sourceDirName + "移動到" + targetDirName + "失敗");
132             return false;
133         }
134     }
135     
136     
137     public static void main(String[] args) {
138         //移動文件,如果目標文件存在,則替換
139         System.out.println("調用moveA_File方法的結果如下");
140         String sourceFileName = "D:\\aa\\temp\\key.txt";
141         String targetFileName = "D:\\bbb\\ddd\\";
142         FileDemo_06.moveA_File(sourceFileName, targetFileName);
143         //移動目錄,如果目標目錄存在,則不覆蓋
144         System.out.println("\n調用moveDir方法的結果如下");
145         String sourceDir = "D:\\aa";
146         String targetDir = "C:\\mm";
147         FileDemo_06.moveDir(sourceDir, targetDir,false);
148     }
149     
150 
151 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM