一、 填空題
- Java IO流可以分為 節點流 和處理流兩大類,其中前者處於IO操作的第一線,所有操作必須通過他們進行。
- 輸入流的唯一目的是提供通往數據的通道,程序可以通過這個通道讀取數據, read
方法給程序提供了一個從輸入流中讀取數據的基本方法。
- read方法從輸入流中順序讀取源中的單個字節數據,該方法返回字節值(0-255之間的一個整數),如果到達源的末尾,該方法返回 -1 。
- Java系統的標准輸入對象是System.in,標准輸出對象有兩個,分別是標准輸出System.out和標准錯誤輸出____System.err__。
- Java IO體系中,___ ObjectInputStream __是字節輸入流,不僅提供了存取所有Java基礎類型數據(如:int,double 等)和String的方法,也提供了提供存取對象的方法。
- Java IO體系中,____ DataOutputStream __是字節輸出流,提供了可以存取所有Java基礎類型數據(如:int,double 等)和String的方法,但沒有提供存取對象的方法。
- ___序列化__是指將Java對象轉換成字節序列,從而可以保存到磁盤上,也可以在網絡上傳輸,使得不同的計算機可以共享對象。
二、 選擇題
1. |
使用Java IO流實現對文本文件的讀寫過程中,需要處理下列( B )異常。(選擇一項) |
|
|
|
|
|
A |
ClassNotFoundException |
|
B. |
IOException |
|
C. |
SQLException |
|
D. |
RemoteException |
2. |
在Java的IO操作中,( D )方法可以用來刷新流的緩沖。(選擇兩項) |
|
|
|
|
|
A |
void release() |
|
B. |
void close() |
|
C. |
void remove() |
|
D. |
void flush() |
3. |
在Java中,下列關於讀寫文件的描述錯誤的是( B )。(選擇一項) |
|
|
|
|
|
A |
Reader類的read()方法用來從源中讀取一個字符的數據 |
|
B. |
Reader類的read(int n )方法用來從源中讀取一個字符的數據 |
|
C. |
Writer類的write(int n)方法用來向輸出流寫入單個字符 |
|
D. |
Writer類的write(String str)方法用來向輸出流寫入一個字符串 |
4. |
閱讀下列文件定入的Java代碼,共有( C )處錯誤。(選擇一項) |
|
|
import java.io.*; public class TestIO { public static void main(String []args){ String str ="文件寫入練習"; FileWriter fw = null; //1 try{ fw = new FileWriter("c:\mytext.txt"); //2 fw.writerToEnd(str); //3 }catch(IOException e){ //4 e.printStackTrace(); }finally{ //此處省略關閉流 } } } |
|
|
|
|
|
A |
0 |
|
B. |
1 |
|
C. |
2 |
|
D. |
3 |
5. |
分析如下Java代碼,有標注的四行代碼中,有錯誤的是第( D )處。(選擇一項) |
|
|
import java.io.FileWriter; import java.io.IOException; public class Test { public static void main(String[ ] args) { String str = "Hello World"; FileWriter fw = null; try { fw = new FileWriter("c:\\hello.txt"); // 1 fw.write(str); // 2 } catch (IOException e) { e.printStackTrace(); // 3 } finally { fw.close(); // 4 } } } |
|
|
|
|
|
A |
1 |
|
B. |
2 |
|
C. |
3 |
|
D. |
4 |
6. |
以下選項中關於如下代碼的說法正確的是( AD )。(選擇二項) |
|
|
public class TestBuffered { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("d:/bjsxt1.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("d:/bjsxt2.txt")); String str = br.readLine(); while(str !=null){ bw.write(str); bw.newLine(); str = br.readLine(); } br.close(); bw.close(); } } |
|
|
|
|
|
A. |
該類使用字符流實現了文件復制,將d:/bjsxt1.txt復制為d:/bjsxt2.txt |
|
B. |
FileReader和FileWriter是處理流,直接從文件讀寫數據 |
|
C. |
BufferedReader和BufferedWriter是節點流,提供緩沖區功能,提高讀寫效率 |
|
D. |
readLine()可以讀取一行數據,返回值是字符串類型,簡化了操作 |
7. |
InputStreamReader是轉換流,可以將字節流轉換成字符流,是字符流與字節流之間的橋梁。它的實現使用的設計模式是( C )。(選擇一項) |
|
|
|
|
|
A. |
工廠模式 |
|
B. |
裝飾模式 |
|
C. |
適配器模式 |
|
D. |
代理模式 |
三、 判斷題
- 假設文件”a.txt”的長度為100字節,那么當正常運行語句”OutputStream f=new FileOutputStream(new File(“a.txt”));”之后,文件”a.txt”的長度變為0字節。( T )
- ByteArrayInutStream和ByteArrayOutputStream對內存中的字節數組進行讀寫操作,屬於字節流,屬於處理流而不是節點流。 ( F )
- 實現Serializable接口的可以被序列化和反序列化。該接口中沒有定義抽象方法,也沒有定義常量。( T )
- 序列化是指將字節序列轉換成Java對象,只有實現了Serializable接口的類的對象才可以被序列化。( F )
四、 簡答題
- 輸入流和輸出流的聯系和區別,字符流和字節流的聯系和區別
- 列舉常用的字節輸入流和字節輸出流並說明其特點,至少5對。
- 說明緩沖流的優點和原理
- 序列化的定義、實現和注意事項
五、 編碼題
1.實現字符串和字節數組之間的相互轉換。必如將字符串“北京尚學堂bjsxt”轉換為字節數組,並將字節數組再轉換回字符串。
1 public class TestConvert 2 { 3 public static void main(String[] args) throws IOException 4 { 5 //准備一個字符串
6 String contents = " 近日,北京尚學堂科技有限公司正式成為央視網廣告合作伙伴"; 7 System.out.println(contents); 8 //String---byte []
9 byte[] buf = contents.getBytes(); 10 //byte[]----String
11 String contents2 = new String(buf, 0, buf.length); 12 System.out.println(contents2); 13 } 14 }
2.實現字節數組和任何基本類型和引用類型執行的相互轉換
提示:使用ByteArrayInutStream和ByteArrayOutputStream。
1 public class TestByteArrayStream 2 { 3 public static void main(String[] args) throws IOException, 4 ClassNotFoundException 5 { 6 int num = 50; 7 boolean flag = true; 8 User user = new User("bjsxt", "bjsxt"); 9 //使用數據包把數據封裝起來 10 //各種數據類型----->byte[] ByteArrayOutputStream
11 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 12 ObjectOutputStream oos = new ObjectOutputStream(baos);//包裝流
13 oos.writeInt(num); 14 oos.writeBoolean(flag); 15 oos.writeObject(user); 16 byte[] buf = baos.toByteArray(); 17 baos.close(); 18 //byte[]----------->各種數據類型
19 ByteArrayInputStream bais = new ByteArrayInputStream(buf); 20 ObjectInputStream ois = new ObjectInputStream(bais); 21 int num2 = ois.readInt(); 22 boolean flag2 = ois.readBoolean(); 23 User user2 = (User) ois.readObject(); 24 System.out.println(num2); 25 System.out.println(flag2); 26 System.out.println(user2); 27 bais.close(); 28 } 29 }
3.分別使用文件流和緩沖流復制一個長度大於100MB的視頻文件,並觀察效率的差異。
1 public class TestCopy4 2 { 3 public static void main(String[] args) throws IOException 4 { 5 //創建輸入流和輸出流
6 InputStream fis = new FileInputStream(new File("d:/1.mp4")); 7 OutputStream fos = new FileOutputStream("d:/2.mp4"); 8 //使用輸入流和輸出流復制文件
9 byte[] buf = new byte[10]; 10 int len = fis.read(buf); 11 while (len != -1) 12 { 13 //寫
14 fos.write(buf, 0, len); 15 //讀
16 len = fis.read(buf); 17 //System.out.println(len);
18 } 19 //關閉輸入流和輸出流
20 fis.close(); 21 fos.close(); 22 } 23 } 24 public class TestCopy 25 { 26 public static void main(String[] args) throws IOException 27 { 28 //創建輸入流和輸出流
29 InputStream fis = new FileInputStream(new File("d:/1.mp4")); 30 OutputStream fos = new FileOutputStream("d:/2.mp4"); 31 BufferedInputStream bis = new BufferedInputStream(fis); 32 BufferedOutputStream bos = new BufferedOutputStream(fos); 33 //使用輸入流和輸出流復制文件
34 byte[] buf = new byte[10]; 35 int len = bis.read(buf); 36 while (len != -1) 37 { 38 //寫
39 bos.write(buf, 0, len); 40 //讀
41 len = bis.read(buf); 42 } 43 //關閉輸入流和輸出流
44 bis.close(); 45 bos.close(); 46 } 47 }
4.復制文件夾d:/sxtjava下面所有文件和子文件夾內容到d:/sxtjava2。
提示:涉及單個文件復制、目錄的創建、遞歸的使用
1 public class CopyDir 2 { 3 /**
4 * 5 * 復制單個文件 6 * 7 * @param sourceFile 源文件 8 * 9 * @param targetFile 目標文件 10 * 11 * @throws IOException 12 * 13 */
14 public static void copyFile(File sourceFile, File targetFile) throws IOException 15 { 16 BufferedInputStream inBuff = null; 17 BufferedOutputStream outBuff = null; 18 try
19 { 20 // 新建文件輸入流
21 inBuff = new BufferedInputStream(new FileInputStream(sourceFile)); 22 // 新建文件輸出流
23 outBuff = new BufferedOutputStream(new FileOutputStream(targetFile)); 24 // 緩沖數組
25 byte[] b = new byte[1024 * 5]; 26 int len; 27 while ((len = inBuff.read(b)) != -1) 28 { 29 outBuff.write(b, 0, len); 30 } 31 // 刷新此緩沖的輸出流
32 outBuff.flush(); 33 } finally
34 { 35 // 關閉流
36 if (inBuff != null) 37 { 38 inBuff.close(); 39 } 40 if (outBuff != null) 41 { 42 outBuff.close(); 43 } 44 } 45 } 46 /**
47 * 48 * 復制目錄 49 * 50 * @param sourceDir 源目錄 51 * 52 * @param targetDir 目標目錄 53 * 54 * @throws IOException 55 * 56 */
57 public static void copyDirectiory(String sourceDir, String targetDir) 58 throws IOException 59 { 60 // 檢查源目錄
61 File fSourceDir = new File(sourceDir); 62 if (!fSourceDir.exists() || !fSourceDir.isDirectory()) 63 { 64 System.out.println("源目錄不存在"); 65 return; 66 } 67 //檢查目標目錄,如不存在則創建
68 File fTargetDir = new File(targetDir); 69 if (!fTargetDir.exists()) 70 { 71 fTargetDir.mkdirs(); 72 } 73 // 遍歷源目錄下的文件或目錄
74 File[] file = fSourceDir.listFiles(); 75 for (int i = 0; i < file.length; i++) 76 { 77 if (file[i].isFile()) 78 { 79 // 源文件
80 File sourceFile = file[i]; 81 // 目標文件
82 File targetFile = new File(fTargetDir, file[i].getName()); 83 copyFile(sourceFile, targetFile); 84 } 85 //遞歸復制子目錄
86 if (file[i].isDirectory()) 87 { 88 // 准備復制的源文件夾
89 String subSourceDir = sourceDir + File.separator + file[i].getName(); 90 // 准備復制的目標文件夾
91 String subTargetDir = targetDir + File.separator + file[i].getName(); 92 // 復制子目錄
93 copyDirectiory(subSourceDir, subTargetDir); 94 } 95 } 96 } 97 public static void main(String[] args) throws IOException 98 { 99 copyDirectiory("d:/sxtjava", "d:/sxtjava2"); 100 } 101 }
可選題
1.使用IO包中的類讀取D盤上exam.txt文本文件的內容,每次讀取一行內容,將每行作為一個輸入放入ArrayList的泛型集合中並將集合中的內容使用加強for進行輸出顯示。
1 public class Test 2 { 3 public static void main(String[] args) throws IOException 4 { 5 String path = "D:\\exam.txt"; 6 outputMethod(path); 7 } 8 public static void outputMethod(String path) throws IOException 9 { 10 List<String> list = new ArrayList<String>(); // 創建集合對象 11 // 創建緩沖區對象
12 BufferedReader br = new BufferedReader(new FileReader(path)); 13 String line = br.readLine(); // 讀取數據每次讀一行
14 while (line != null) 15 { 16 list.add(line); 17 line = br.readLine(); 18 } 19 br.close(); //關閉
20 for (String s : list) 21 { 22 System.out.println(s); 23 } 24 } 25 }
2.假設從入學開始所有書寫的Java類代碼都在d:/sxtjava文件夾下,包括多級子文件夾。使用IO流獲取從入學開始,到目前為止已經寫了多少行Java代碼。
提示:
其實就是獲取d:/sxtjava文件夾及其子文件夾下的所有.java文件,使用readLine()讀取其中每一行,每讀取一行,行數加1。所有的文件讀取完畢,得到總共已經寫的Java代碼行數。需要結合遞歸實現。
1 public class TestCountDir 2 { 3 private int count; 4 /**
5 * 6 * 統計一個java文件的行數 7 * 8 */
9 private void countLine(File sourceFile) throws IOException 10 { 11 BufferedReader br = null; 12 try
13 { 14 // 新建文件輸入流
15 br = new BufferedReader(new FileReader(sourceFile)); 16 while (br.readLine() != null) 17 { 18 count++; 19 //System.out.println(count);
20 } 21 } finally
22 { 23 br.close(); 24 } 25 } 26 /**
27 * 28 * 統計一個目錄下所有Java文件的行數 29 * 30 */
31 private void countDir(String sourceDir) throws IOException 32 { 33 // 檢查源目錄
34 File fSourceDir = new File(sourceDir); 35 if (!fSourceDir.exists() || !fSourceDir.isDirectory()) 36 { 37 System.out.println("源目錄不存在"); 38 return; 39 } 40 // 遍歷目錄下的文件或目錄
41 File[] file = fSourceDir.listFiles(); 42 for (int i = 0; i < file.length; i++) 43 { 44 if (file[i].isFile()) 45 { 46 if (file[i].getName().toLowerCase().endsWith(".java")) 47 { 48 // System.out.println(file[i].getName());
49 countLine(file[i]); 50 } 51 } 52 //遞歸統計代碼行數
53 if (file[i].isDirectory()) 54 { 55 // 准備統計的文件夾
56 String subSourceDir = sourceDir + File.separator + file[i].getName(); 57 // 統計子目錄
58 countDir(subSourceDir); 59 } 60 } 61 } 62 public static void main(String[] args) throws IOException 63 { 64 TestCountDir tcd = new TestCountDir(); 65 tcd.countDir("d:/sxtjava"); 66 System.out.println(tcd.count); 67 } 68 }
3.由控制台按照固定格式輸入學生信息,包括學號,姓名,年齡信息,當輸入的內容為exit退出;將輸入的學生信息分別封裝到一個Student對象中,再將每個Student對象加入到一個集合中,要求集合中的元素按照年齡大小正序排序;最后遍歷集合,將集合中學生信息寫入到記事本,每個學生數據占單獨一行。
1 public class Student implements Comparable<Student>
2 { 3 private Integer num; 4 private String name; 5 private Integer age; 6 //省略getter和setter方法 7 //省略構造方法
8 public int compareTo(Student stu) 9 { 10 return this.age - stu.age; 11 } 12 public String toString() 13 { 14 return "Student [age=" + age + ", name=" + name 15 + ", num=" + num + "]"; 16 } 17 } 18 public class Test 19 { 20 public static void main(String[] args) 21 { 22 Set<Student> stuSet = saveStudentInfo(); 23 outputInfo(stuSet); 24 } 25 private static Set<Student> saveStudentInfo() 26 { 27 Scanner input = new Scanner(System.in); 28 // 保存學生信息的TreeSet集合對象
29 Set<Student> stuSet = new TreeSet<Student>(); 30 while (true) 31 { 32 // 輸入提示
33 System.out.println("請輸入學生信息:(學號#姓名#年齡)"); 34 String inputData = input.nextLine(); 35 // 判斷是否退出 inputData.equals("exit")
36 if ("exit".equals(inputData)) 37 { 38 break; 39 } 40 // 將用戶輸入的學生信息分割為String[]
41 String[] info = inputData.split("#"); 42 // 將輸入信息封裝到Student對象中
43 Student stu 44 = new Student(Integer.parseInt(info[0]), info[1], 45 Integer.parseInt(info[2])); 46 // 將學生對象加入集合
47 stuSet.add(stu); 48 } 49 return stuSet; 50 } 51 private static void outputInfo(Set<Student> stuSet) 52 { 53 File file = new File("e:/student.txt"); 54 // 創建文件輸出流對象
55 FileWriter fw = null; 56 try
57 { 58 fw = new FileWriter(file); 59 Iterator<Student> it = stuSet.iterator(); 60 while (it.hasNext()) 61 { 62 String info = it.next().toString(); 63 // 將info字符串,寫入記事本
64 fw.write(info); 65 // 完成換行功能
66 fw.write("\r\n"); 67 } 68 } catch (Exception e) 69 { 70 e.printStackTrace(); 71 } finally
72 { 73 try
74 { 75 fw.close(); 76 } catch (IOException e) 77 { 78 e.printStackTrace(); 79 } 80 } 81 } 82 }