java io流練習,建議可以跟着敲敲,這些在面試中常會遇到,希望對大家有幫助...
Java IO流經典練習題
本文對javaIO流的13道經典的練習題做解答,里面有詳細的思路解析,做題時最好養成先寫思路在編程的習慣。
一.練習的題目
(一) 在電腦D盤下創建一個文件為HelloWorld.txt文件,判斷他是文件還是目錄,在創建一個目
錄IOTest,之后將HelloWorld.txt移動到IOTest目錄下去;之后遍歷IOTest這個目錄下的文
件
(二) 遞歸實現輸入任意目錄,列出文件以及文件夾,效果看圖
(三) 遞歸實現列出當前工程下所有.java文件
(四)從磁盤讀取一個文件到內存中,再打印到控制台
(五) 在程序中寫一個"HelloJavaWorld你好世界"輸出到操作系統文件Hello.txt文件中
(六) 拷貝一張圖片,從一個目錄到另外一個目錄下(PS:是拷貝是不是移動)
(七) 統計一個文件calcCharNum.txt(見附件)中字母'A'和'a'出現的總次數
(八)統計一個文件calcCharNum.txt(見附件)中各個字母出現次數:
A(8),B(16),C(10)...,a(12),b(10),c(3)....,括號內代表字符出現次數;
(九)統計一個文件calcCharNum2.txt(見附件)中各個字母出現次數:
A(8),B(16),C(10)...,a(12),b(10),c(3)....中(5),國(6),括號內代表字符出現次數;
(十) 使用隨機文件流類RandomAccessFile將一個文本文件倒置讀出。
(十一) 編寫一個Java應用程序,可以實現Dos中的type命令,並加上行號。
即將文本文件在控制台上顯示出來,並在每一行的前面加上行號。
(十二)輸入兩個文件夾名稱,將A文件夾內容全部拷貝到B文件夾,要求使用多線程來操作。
(十三)查看D盤中所有的文件和文件夾名稱,並且使用名稱升序降序,文件夾在前和文件夾在
后,文件大小排序等。
二.詳細的解題過程
(一)第一題
package Java_Learn; import java.io.File; import java.io.IOException; public class Test { public static void main(String[] args) { //在電腦D盤下創建一個文件為HelloWorld.txt文件 File file=new File("C:\\文檔\\個人學習資料","HelloWorld.txt"); //創建文件,返回一個布爾值 boolean isCreate; try { isCreate = file.createNewFile(); if (isCreate) { System.out.println("創建文件成功!"); }else { System.out.println("創建文件失敗!文件已經存在"); } } catch (IOException e) { System.out.println("創建文件失敗!"); } // 判斷他是文件還是目錄, if (file.isFile()) { System.out.println("這是一個文件"); } else { System.out.println("這是一個目錄"); } //再創建一個目錄IOTest File file2=new File("C:\\文檔\\個人學習資料/IOTest"); file2.mkdirs(); //HelloWorld.txt移動到IOTest目錄下去?失敗?》 if (file.renameTo(new File(file2.getAbsolutePath() + "/" + file.getName()))) { System.out.println("文件移動成功!"); } else { System.out.println("文件移動失敗"); } //遍歷IOTest目錄下的文件 String[] arr=file2.list(); for (String string : arr) { System.out.println(string); } } }
//上面移動文件要指明文件路徑和文件名
上面的file.renameTo(file2)改為:
file.renameTo(file2.getPath + "/" + file.getName());
就不會有錯了。
(二)第二題
1.先建一個FileUtile工具類
package com.xykj.lesson2; import java.io.File; import java.util.ArrayList; import java.util.List; /** * 這是一個獲取目錄下所有文件夾內的所有文件的封裝類 * 當然前提是你要傳進來一個正確路徑的文件夾 * */ public class FileUtils { //獲取文件夾下所有的文件 public static List<File> getAllFiles(String dir){ //創建一個集合存放遍歷到的File List< File >files=new ArrayList<File>(); File file=new File(dir); //文件夾必須存在 並且要是文件夾 if (file.exists()&&file.isDirectory()) { //重點! 這里要本身一直遍歷 longErgodic(file,files);//把遍歷得到的東西存放在files里面 } return files; } //重點理解,這是一個遞歸方法,會不斷來回調用本身,但是所有獲得的數據都會存放在集合files里面 private static void longErgodic(File file, List<File> files) { //.listFiles()方法的使用 //把文件夾的所有文件(包括文件和文件名)都放在一個文件類的數組里面 File[] fillArr=file.listFiles(); //如果是一個空的文件夾 if (fillArr==null) { //后面的不執行,直接返回 return; } //如果文件夾有內容,遍歷里面的所有文件(包括文件夾和文件),都添加到集合里面 for (File file2 : fillArr) { //如果只是想要里面的文件或者文件夾或者某些固定格式的文件可以判斷下再添加 files.add(file2); //添加到集合后,在來判斷是否是文件夾,再遍歷里面的所有文件 //方法的遞歸 longErgodic(file2, files); } } }
2.再建一個主方法調用類
package com.xykj.lesson2; import java.io.File; import java.util.List; public class Test2 { /** * 遞歸實現輸入任意目錄,列出文件以及文件夾 * * 設計:在FileUtils類里面實現了邏輯操作,在另一邊調用就可以了 * */ public static void main(String[] args) { //比如輸入D盤 List<File>list=FileUtils.getAllFiles("D:"); //輸出所有的文件和文件夾的名字 for (File file : list) { System.out.println(file); } } }
(三)第三題
package com.xykj.lesson3; import java.io.File; import java.util.List; import com.xykj.lesson2.FileUtils; public class Test3 { /** * 遞歸實現列出當前工程下所有.java文件 * 還是要題目2的遍歷文件的工具類來獲取所有的文件,再過濾.java文件就可以了 * 當前目錄的地址:輸入.就可以獲取 * */ public static void main(String[] args) { //輸入. 獲取當前文件的 所有文件 List<File>list=FileUtils.getAllFiles("."); //輸出.java后綴的文件的名字 for (File file : list) { if (file.toString().endsWith(".java")) { System.out.println(file.getName()); } } } }
(四)第四題
package com.xykj.lesson4; import java.io.File; import java.io.FileInputStream; public class Tset4 { /** * 從磁盤讀取一個文件到內存中,再打印到控制台 * * 程序設計: * 1、讀取文件用到FileinputSteam * 2、把讀取的內容不斷加入到StringBuffer, * 3、再把StringBuffer打印出來就可以 * */ public static void main(String[] args) { // 讀取D:\notePad\aa.txt里面的內容 File file = new File("D:\\notePad\\aa.txt"); try { // 創建讀取流即輸入流 FileInputStream fis = new FileInputStream(file); int len = 0; byte[] buf = new byte[1024]; StringBuffer sb = new StringBuffer(); // 把讀取的數據添加到StringBuffer里面 while ((len = fis.read(buf)) != -1) { sb.append(new String(buf, 0, len)); } // 把StringBuffer里面的內容打印出來 System.out.println(sb); fis.close(); } catch (Exception e) { e.printStackTrace(); } } }
(五)第五題
package com.xykj.lesson5; import java.io.File; import java.io.FileOutputStream; public class Test5 { /** * 在程序中寫一個"HelloJavaWorld你好世界"輸出到操作系統文件Hello.txt文件中 * * 程序分析:文件寫入,要用到輸出流FileOutputStream * */ public static void main(String[] args) { // 向文件D:/Hello.txt,寫入內容 File file = new File("D:/Hello.txt"); try { // 創建輸出流 FileOutputStream fos = new FileOutputStream(file); //把String類型的字符串轉化為byte數組的數據保存在輸出流中 fos.write("HelloJavaWorld你好世界".getBytes()); fos.flush();//刷新輸出流 fos.close();//關閉輸出流 } catch (Exception e) { e.printStackTrace(); } } }
(六)第六題
package com.xykj.lesson6; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; public class Test6 { /** * 拷貝一張圖片,從一個目錄到另外一個目錄下(PS:是拷貝是不是移動) * * 程序設計思路: * 這題不能使用renameTo, * 解題步驟: * 1、在目的地址創建一個圖片文件 * 2、讀取源地址文件的字節流 * 3、把讀取到的字節流寫入到目的地址的文件里面 * 4、刷新輸出流,並關閉就可以了 * * @throws Exception * */ public static void main(String[] args) { // 本題示范把D盤下的mm.jpg復制到D盤java文件夾里面 // 源文件地址 File fileFrom = new File("D:/mm.jpg"); // 目的文件地址 File fileTo = new File("D:/java/mm.jpg"); // 1、創建目的文件地址 try { if (!fileTo.createNewFile()) { System.out.println("創建文件失敗!"); } // 2、讀取源地址文件的字節流 FileInputStream fis = new FileInputStream(fileFrom); FileOutputStream fos = new FileOutputStream(fileTo); int len = 0; byte[] buf = new byte[1024]; while ((len = fis.read(buf)) != -1) { // 3、把讀取到的字節流寫入到目的地址的文件里面 fos.write(buf, 0, len); } // 刷新下輸出流 fos.flush(); // 關閉輸入流和輸出流 fis.close(); fos.close(); System.out.println("文件復制成功!"); } catch (Exception e) { e.printStackTrace(); } } }
(七)第七題
package com.xykj.lesson7; import java.io.File; import java.io.FileInputStream; public class Test7 { /** * 統計一個文件calcCharNum.txt(見附件)中字母'A'和'a'出現的總次數 * * 程序分析: * 讀取文件用FileInputStream * 一次只讀一個字節(一個字母就是一個字節),當字節內容和A或a相等時,相應的數量加1 * */ public static void main(String[] args) { try { //添加文件路徑 File file = new File("D:/java/calcCharNum.txt"); //創建文件讀取流 FileInputStream fis = new FileInputStream(file); int numA = 0;//字母A的數量 int numa = 0;//字母a的數量 int len = 0;//每次讀取的字節數量 while ((len=fis.read())!= -1) { //統計字母a的數量 if (new String((char)len+"").equals("a")) { numa++; } //統計字母A的數量 if (new String((char)len+"").equals("A")) { numA++; } } //打印出文件內字母的數量 System.out.println("a的數量是:"+numa); System.out.println("A的數量是:"+numA); System.out.println("a和A出現的總次數:"+(numA+numa)); fis.close();//關閉輸入流 } catch (Exception e) { e.printStackTrace(); } } }
(八)第八題
package com.xykj.lesson8; import java.io.File; import java.io.FileInputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; public class Test8 { /** * 統計一個文件calcCharNum.txt(見附件)中各個字母出現次數: * A(8),B(16),C(10)...,a(12),b(10),c(3)....,括號內代表字符出現次數; * * 程序分析: * 1.這里沒中文字符,依然可以只用字節流來讀取文件 * 2.不能保存相同的主鍵值,可以使用HashMap:key-value來實現 * 3.先獲得該key的value,如果存在key的話value的值加1 * */ public static void main(String[] args) { // 文件路徑 File file = new File("D:/java/calcCharNum.txt"); try { // 創建讀取文件的輸入流 FileInputStream fis = new FileInputStream(file); // 創建集合HashMap類存放要保存的key-value HashMap<String, Integer> map = new HashMap<>(); // 讀取文件 int len = 0;// 每次讀取的文件長度 int count = 0; while ((len = fis.read()) != -1) { // 每次獲取到的字母 char c = (char) len; //這里使用try catch是因為 map.get(c + ""),第一次get不到東西會出現空指針 try { // 通過每次的key值獲取它的value值, // 但是在它的key值沒有時或報空指針錯誤,所以要try catch處理 // 當她有key值,就可以獲取到相應的value值 count = map.get(c + ""); } catch (Exception e) {// 什么都不用輸出 } // 如果有它的key值對應的value值要加1 map.put(c + "", count + 1); } fis.close(); // 讀完后把結果打印出來 //迭代器的使用 Iterator<Entry<String, Integer>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Entry<String, Integer> entry = iterator.next(); System.out.print(entry.getKey() + "(" + entry.getValue()+ ") \t"); } } catch (Exception e) { e.printStackTrace(); } } }
其實本題也可以直接用字符流來讀取的。
(九)第九題
package com.xykj.lesson9; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; public class Test9 { /** * 統計一個文件calcCharNum2.txt(見附件)中各個字母出現次數: * A(8),B(16),C(10)...,a(12),b(10),c(3)....中(5),國(6), * 括號內代表字符出現次數; * * 程序分析: * 1.這出現中文字符,依然只能用字符流來讀取文件 * 2.不能保存相同的主鍵值,可以使用HashMap:key-value來實現 * 3.先獲得該key的value,如果存在key的話value的值加1 * */ public static void main(String[] args) { // 文件路徑 File file = new File("D:/java/calcCharNum2.txt"); // 創建集合HashMap類存放要保存的key-value HashMap<String, Integer> map = new HashMap<>(); try { // 創建字符流 FileReader fr = new FileReader(file); // 每次讀取的字符長度 int len = 0; int count=0;//出現該字符的次數 while ((len = fr.read()) != -1) { // 獲取對應的字符 char c = (char) len; try { // 通過每次的key值獲取它的value值, // 但是在它的key值沒有時或報空指針錯誤,所以要try catch處理 // 當她有key值,就可以獲取到相應的value值 count = map.get(c + ""); } catch (Exception e) {// 什么都不用輸出 } // 如果有它的key值對應的value值要加1 map.put(c + "", count + 1); } // 讀完后把結果打印出來 Iterator<Entry<String, Integer>> iterator = map.entrySet().iterator(); //迭代器的使用 while (iterator.hasNext()) { Entry<String, Integer> entry = iterator.next(); System.out.print(entry.getKey() + "(" + entry.getValue()+ ") \t"); } } catch (Exception e) { e.printStackTrace(); } } }
(十)第十題
package com.xykj.lesson10; import java.io.File; import java.io.RandomAccessFile; public class Test10 { /** * 使用隨機文件流類RandomAccessFile將一個文本文件倒置讀出。 * * 程序分析: * RandomAccessFile的seek方法能把讀取文件的光標移動到具體的位置 * 但是還是有地點值得注意的是一個字母或數字是占用一個字節的, 一個漢字是占用兩個字節的 * */ public static void main(String[] args) { // 要讀取的文件的地址 File file = new File("D:/java/calcCharNum2.txt"); try { RandomAccessFile raf = new RandomAccessFile(file, "r"); long length = raf.length(); StringBuffer sb = new StringBuffer(); while (length > 0) { length--; raf.seek(length); int c = (char) raf.readByte(); // 如果asc碼<=255,>=0,則判斷是個英文字符,添加到字符串中. if (c >= 0 && c <= 255) { sb.append((char) c); } else { // 如果不在asc碼范圍內,則判斷是個漢字字符 // 漢字字符是占2個字節的,所以length再退一個字節 length--; raf.seek(length); byte[] cc = new byte[2]; // cc被復制為文件中連續的兩個字節 raf.readFully(cc); sb.append(new String(cc)); } } System.out.println(sb); raf.close(); } catch (Exception e) { e.printStackTrace(); } } }
(十一)第十一題
package com.xykj.lesson1; import java.io.File; import java.io.IOException; public class Test1 { /** * 1. 在電腦D盤下創建一個文件為HelloWorld.txt文件, * 判斷他是文件還是目錄,再創建一個目錄IOTest, * 之后將HelloWorld.txt移動到IOTest目錄下去; * 之后遍歷IOTest這個目錄下的文件 * * 程序分析: * 1、文件創建使用File的createNewFile()方法 * 2、判斷是文件用isFile(),判斷是目錄用isDirectory * 3、創建目錄用:mkdirs()方法 * 4、移動文件用:renameTo * 5、遍歷目錄用:list()方法獲得存放文件的數組,foreach遍歷的方法把文件打印出來 * */ public static void main(String[] args) { //在電腦D盤下創建一個文件為HelloWorld.txt文件 File file=new File("D:","HelloWorld.txt"); //創建文件,返回一個布爾值 boolean isCreate; try { isCreate = file.createNewFile(); if (isCreate) { System.out.println("創建文件成功!"); }else { System.out.println("創建文件失敗!文件已經存在"); } } catch (IOException e) { System.out.println("創建文件失敗!"); } // 判斷他是文件還是目錄, if (file.isFile()) { System.out.println("這是一個文件"); } else { System.out.println("這是一個目錄"); } //再創建一個目錄IOTest File file2=new File("D:/IOTest"); file2.mkdirs(); //HelloWorld.txt移動到IOTest目錄下去?失敗?》 if (file.renameTo(file2)) { System.out.println("文件移動成功!"); } else { System.out.println("文件移動失敗"); } //遍歷IOTest目錄下的文件 String[] arr=file2.list(); for (String string : arr) { System.out.println(string); } } }
(十二)第十二題
package com.xykj.lesson12; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.xykj.lesson2.FileUtils; public class Test12 { /* * 輸入兩個文件夾名稱,將A文件夾內容全部拷貝到B文件夾,要求使用多線程來操作。 * * 程序分析: * 1.拷貝文件里面的東西,要分析的東西還是蠻多的,要先建文件夾再拷貝里面的東西,而且要一層層的來搞 * 2.這里也需要文件遍歷工具,直接調用第二題的工具類,不再重寫 * 3.多線程的使用,可以直接在方法里面直接新建線程 * 4.對整個文件夾進行復制 文件夾分隔符可以用\\或/,其他的都是不對的 * 所有其中還對輸入的分割符進行了替換 * 這題看起來比較長,分開看其實也不長 * */ public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println("要復制的文件夾:"); String fromDir = scanner.next();// 接收輸入 System.out.println("要復制到哪里去:"); String toDir = scanner.next();// 接收輸入 // 把輸入的地址轉化為File類型 File fromFile = new File(fromDir); File toFile = new File(toDir); //新建線程 new Thread(){ //里面做實際操作 public void run() { // 判斷如果要復制的是文件,直接復制就可以了 if (fromFile.isFile()) { System.out.println("復制單個文件"); copy(fromFile, toFile); } else { // 要復制文件夾 // 要防止一種無法進行的復制:比如說,要把復制的文件復制到自己的子文件夾里面 // 舉個例子:把D:/java/jsp文件夾復制到D:/java/jsp/js文件夾里面, // 這會導致子文件不斷增加的同時,而父文件也要不斷增加,的一個死循環 // 如果反過來,就沒事,相當於只是簡單的覆蓋而已 // 具體實現就是看:目的地地址包含復制的文件夾地址,就不允許操作 if (toDir.replace("/", "\\").toLowerCase() .startsWith(fromDir.replace("/", "\\").toLowerCase())) { return; } // 復制文件(包括文件和文件夾)操作 // 先獲取所有的文件(包括文件和文件夾) List<File> list = FileUtils.getAllFiles(fromDir); // 創建一個線程池,加快復制的速度 ExecutorService threadPool = Executors.newFixedThreadPool(20); // 需要對每一個文件的路徑進行處理 for (File file : list) { // 復制文件名 String name = file.getAbsolutePath(); // 把原來的文件路徑換成新的文件路徑 String toName = name.replace(fromFile.getParent(), toDir + "/"); System.out.println(name + "變成了" + toName); // 如果是文件夾,直接創建 if (file.isDirectory()) { new File(toName).mkdirs(); } else { // 如果是文件,在線程里面復制 threadPool.execute(new Runnable() { @Override public void run() { File copyFile = new File(toName); // 先要有父文件夾 copyFile.getParentFile().mkdirs(); // 開始復制文件 copy(file, copyFile); } }); } } } scanner.close(); }; }.start();//開始線程 } //復制文件的操作 public static void copy(File fromFile, File toFile) { // 定義一個輸入流 FileInputStream fis = null; // 定義一個輸出流 FileOutputStream fos = null; try { // 把復制地址的File,封裝后賦值給輸入流對象 fis = new FileInputStream(fromFile); // 把目的地的File,封裝后復制給輸出流的對象 fos = new FileOutputStream(toFile); // 創建一個容量, byte[] buf = new byte[1024]; // 每次讀取/寫入的字節長度 int len = 0; // 邊讀邊寫 while ((len = fis.read(buf)) != -1) {// 判斷是否還能讀到數據 // 把輸入放到輸出流里面 fos.write(buf, 0, len); } } catch (Exception e) { e.printStackTrace(); } finally { try { // 關閉輸入流和輸出流 fis.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
(十三)第十三題
package com.xykj.lesson13; import java.io.File; import java.util.Collections; import java.util.Comparator; import java.util.List; import com.xykj.lesson2.FileUtils; public class Test13 { /** * 查看D盤中所有的文件和文件夾名稱,並且使用名稱升序降序, * 文件夾在前和文件夾在后,文件大小排序等。 * * 程序分析: * 1.查找文件和文件夾,需要例題二里遍歷文件的工具類(這里直接調用,不在重寫) * 2.排序需要用到list集合里面的Collections工具類類的sort方法 * 3.這里有三重排序:首先是要按是否是文件夾來排序,然后按名稱來排序,最后按大小來排序 * 其實這里還是會有問題的,按照某一個排序還沒事,但是三個都排序就不一定有效! 實際應用中也是只按一種排序就可以了的 * */ public static void main(String[] args) { List<File> list =FileUtils.getAllFiles("D:"); //按文件夾先顯示的順序: Collections.sort(list, new Comparator<File>() { @Override public int compare(File o1, File o2) { return (o2.isDirectory()?1:-1)-(o1.isDirectory()?1:-1); } }); //按文件名稱顯示的順序: Collections.sort(list, new Comparator<File>() { @Override public int compare(File o1, File o2) { return (o1.getName()).compareTo(o2.getName()); } }); //按文件名稱顯示的順序: Collections.sort(list, new Comparator<File>() { @Override public int compare(File o1, File o2) { return (int)(o1.length()-o2.length()); } }); //遍歷集合的文件 for (File file : list) { //打印排序后的文件或文件夾 System.out.println(file.getName()); } } }
但是對於基本的解題方式還是要了解的。對於知識點的掌握的話,
文件的基本操作,讀取文件的基本方法,和寫文件的基本方法都是要掌握的,
還有字節流的讀取和字符流的讀取方式和用處也要會區分。