Java第09次實驗(IO流)--實驗報告


0.字節流與二進制文件

我的代碼

  • 用DataOutputStream和FileOutputStream將Student對象寫入二進制文件student.data
package test;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class StudentFile {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		String fileName = "d:/student.data";
		try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(fileName))) {
			Student s = new Student(1, "wang", 19, 89);
			dos.writeInt(stu1.getId());
			dos.writeUTF(stu1.getName());
			dos.writeInt(stu1.getAge());
			dos.writeDouble(stu1.getGrade());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try (DataInputStream dis = new DataInputStream(new FileInputStream(fileName))) {
			int id = dis.readInt();
			String name = dis.readUTF();
			int age = dis.readInt();
			double grade = dis.readDouble();
			Student stu = new Student(id, name, age, grade);
			System.out.println(stu);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

我的總結

  • 二進制文件與文本文件的區別
    • 二進制文件可以儲存基本數據類型的變量
    • 文本文件只能儲存基本數據類型中的char類型變量。
  • try...catch...finally的注意事項
    • catch多個異常時要注意異常的先后順序。父類異常應放在最后。
  • 使用try...catch...resouces關閉資源
    • 可以直接在try后面加一個括號,在括號中定義最后要關閉的資源。這樣,不需要在catch后面加上finally,程序運行結束之后資源會自動關閉。

1.字符流與文本文件

我的代碼

  • 使用BufferedReader從編碼為UTF-8的文本文件中讀出學生信息,並組裝成對象然后輸出。
package test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {
	public static void main(String[] args) {
		String fileName="d:/Students.txt";
		List<Student> studentList = new ArrayList<>();
		        try(
		            FileInputStream fis=new FileInputStream(fileName);
		            InputStreamReader isr=new InputStreamReader(fis, "UTF-8");
		            BufferedReader br=new BufferedReader(isr))
		        {
		            String line=null;
		            while((line=br.readLine())!=null)
		            {
		                String[] msg=line.split("\\s+");
		                int id=Integer.parseInt(msg[0]);
		                String name=msg[1];
		                int age=Integer.parseInt(msg[2]);
		                double grade=Double.parseDouble(msg[3]);
		                Student stu=new Student(id,name,age,grade);
		                studentList.add(stu);
		            }
		        } 
		        catch (FileNotFoundException e)
		        {
		            // TODO Auto-generated catch block
		            e.printStackTrace();
		        } 
		        catch (IOException e) 
		        {
		            // TODO Auto-generated catch block
		            e.printStackTrace();
		        }
		        System.out.println(studentList);

	}
}
  • 編寫public static ListreadStudents(String fileName);從fileName指定的文本文件中讀取所有學生,並將其放入到一個List中
public static List<Student> readStudents(String fileName)
    {
        List<Student> stuList = new ArrayList<>();
        try(
            FileInputStream fis=new FileInputStream(fileName);
            InputStreamReader isr=new InputStreamReader(fis, "UTF-8");
            BufferedReader br=new BufferedReader(isr))
        {
            String line=null;
            while((line=br.readLine())!=null)
            {
                String[] msg=line.split("\\s+");
                int id=Integer.parseInt(msg[0]);
                String name=msg[1];
                int age=Integer.parseInt(msg[2]);
                double grade=Double.parseDouble(msg[3]);
                Student stu=new Student(id,name,age,grade);
                stuList.add(stu);
            }
        } 
        catch (FileNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (IOException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return stuList;
    }
  • 使用PrintWriter將Student對象寫入文本文件
package test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class WriteFile {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String fileName = "d:/Students.txt";
		try (FileOutputStream fos = new FileOutputStream(fileName, true);
				OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
				PrintWriter pw = new PrintWriter(osw)) {
			pw.println("1 zhang 18 85");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
  • 使用ObjectInputStream/ObjectOutputStream讀寫學生對象。
package test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class WriteFile {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String fileName="d:/Students.dat";
		try(
		            FileOutputStream fos=new FileOutputStream(fileName);
		            ObjectOutputStream oos=new ObjectOutputStream(fos))
		        {
		            Student ts=new Student(1,"lily",64,90);
		            oos.writeObject(ts);
		        }
		        catch (Exception e) {
		            // TODO Auto-generated catch block
		            e.printStackTrace();
		        }
		        try(
		            FileInputStream fis=new FileInputStream(fileName);
		            ObjectInputStream ois=new ObjectInputStream(fis))
		        {
		            Student newStudent =(Student)ois.readObject();
		            System.out.println(newStudent);
		        } catch (IOException e) {
		            // TODO Auto-generated catch block
		            e.printStackTrace();
		        } catch (ClassNotFoundException e) {
		            // TODO Auto-generated catch block
		            e.printStackTrace();
		        }
	}

}

我的總結

  • 在構造FileOutputStream時應該多傳一個true來避免PrintWriter直接覆蓋原文件。
  • writeObject()函數的作用:讓實例以文件的形式保存在磁盤上。

2.緩沖流

我的代碼

  • 使用PrintWriter往文件里寫入一千萬行的隨機整數,范圍在[0,10],隨機種子為100.
package test;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Random;

public class WriteFile {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String fileName = "d:/bigdata.txt";
		int n = 1000_0000;
		Random r = new Random(100);
		try(PrintWriter pw = new PrintWriter(fileName)){
			for(int i=0;i<n;i++) {
				pw.println(r.nextInt(11));
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

  • JUNIT測試部分,測試BufferedReader與Scanner的讀文件的效率
package test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

import org.junit.jupiter.api.Test;

class TestRead {
	String fileName = "d:/bigdata.txt";
	
	/*BufferedReader讀取文件*/
	@Test
	void testB() {
		try(BufferedReader br = new BufferedReader(new FileReader(new File(fileName)))){
			String str = null;
			int count = 0;
			long sum = 0;
			while((str = br.readLine()) != null) {
				int num = Integer.parseInt(str);
				sum += num;
				count++;
			}
                        System.out.println("BufferedReader:");
			System.out.format("count=%d,sum=%d,average=%.5f\n",count,sum,sum*1.0/count);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/*Scanner讀取文件*/
	@Test
	void testS() {
		try(Scanner sc = new Scanner(new File(fileName))){
			int count = 0;
			long sum = 0;
			while(sc.hasNextLine()) {
				String str = sc.nextLine();
				int num = Integer.parseInt(str);
				count++;
				sum += num;
			}
                        System.out.println("Scanner:");
			System.out.format("count=%d,sum=%d,average=%.5f\n",count,sum,sum*1.0/count);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

  • JUNIT測試結果

我的總結

  • 一開始的時候,我把Random放在了try…catch的for循環里面,導致每次都新建一個隨機種子為100的Random對象,導致每次生成的數字都是4,在老師的提醒下,才發現Random類對象只要定義一個就好了。
  • 將隨機數寫入文件的時候,一開始我忘記設置隨機種子了,導致文件中的數據平均值不是一個定值。
  • JUNIT中要測試的方法前要加上@Test。

3.字節流之對象流

結合使用ObjectOutputStream、ObjectInputStream與FileInputStream、FileOuputStream實現對Student對象的讀寫。
編寫如下兩個方法:

  • public static void writeStudent(List stuList)
  • public static List readStudents(String fileName)

我的代碼

	public static void writeStudent(List<Student> stuList)
    {
        String fileName="d:/Students.dat";
        try (   FileOutputStream fos=new FileOutputStream(fileName);
                ObjectOutputStream ois=new ObjectOutputStream(fos))
        {
            ois.writeObject(stuList);
            
        } 
        catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
public static List<Student> readStudents(String fileName)
    {
        List<Student> stuList=new ArrayList<>();
        try (   FileInputStream fis=new FileInputStream(fileName);
                ObjectInputStream ois=new ObjectInputStream(fis))
        {
            stuList=(List<Student>)ois.readObject();
        } 
        catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return stuList;
    } 

我的總結

  • 使用對象流的時候,寫入的是一個對象,而不是多個對象。所以在讀取的時候不能像BufferedReader一樣一行一行的讀取,而是直接讀取出一個集合。

5.文件操作

編寫一個程序,可以根據指定目錄和文件名,搜索該目錄及子目錄下的所有文件,如果沒有找到指定文件名,則顯示無匹配,否則將所有找到的文件名與文件夾名顯示出來。
編寫public static void findFile(Path dir,String fileName)方法.
以dir指定的路徑為根目錄,在其目錄與子目錄下查找所有和filename
相同的文件名,一旦找到就馬上輸出到控制台。

我的代碼

遞歸方法

package test;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Path dir = Paths.get("D:\\", "testStream", "5");
		findFile(dir, "c.txt");
	}

	public static void findFile(Path dir, String fileName) {
		File file = dir.toFile();
		File[] files = file.listFiles();
		for (File now : files) {
			if (now.isFile()) {
				if (now.getName().equals(fileName)) {
					System.out.println(now.getAbsolutePath());
					return;
				}
			} else if (now.isDirectory()) {
				findFile(now.toPath(), fileName);
			}
		}
	}
}

我的總結

  • File類和Path類可以互相轉化。
  • Paths類可以直接獲得Path對象。

6.正則表達式

我的代碼

  • 如何判斷一個給定的字符串是否是10進制數字格式?嘗試編程進行驗證。
package test;

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

	public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        Pattern pattern=Pattern.compile("^[+-]?[0-9]+(\\.\\d+)?");
        Matcher matcher=null;
        while(sc.hasNext())
        {
            String str=sc.next();
            matcher=pattern.matcher(str);
            System.out.println(matcher.matches());
        }
        sc.close();
    }

}
  • 修改HrefMatch.java
    • 匹配網頁中的數字字符串
package test;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class HrefMatch {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try
	      {
	         // get URL string from command line or use default
	         String fileName="D:\\test\\File\\HrefMatch.htm";
	         // open reader for URL
	         InputStreamReader in = new InputStreamReader(new FileInputStream(fileName));
	         // read contents into string builder
	         StringBuilder input = new StringBuilder();
	         int ch;
	         while ((ch = in.read()) != -1)
	            input.append((char) ch);

	         String patternString = "[+-]?[0-9]+(\\.\\d+)?";
	         Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
	         Matcher matcher = pattern.matcher(input);

	         while (matcher.find())
	         {
	            int start = matcher.start();
	            int end = matcher.end();
	            String match = input.substring(start, end);
	            System.out.println(match);
	         }
	      }
	      catch (IOException e)
	      {
	         e.printStackTrace();
	      }
	      catch (PatternSyntaxException e)
	      {
	         e.printStackTrace();
	      }
	}
}

我的總結

  • 正則表達式理解的還不是很透徹,匹配圖片字符串的要求還沒有完成。


免責聲明!

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



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