Java第09次实验(IO流) - 实验报告

0. 字节流与二进制文件

我的代码


public class Main {
    public static void main(String[] args)
    {
        String fileName="d:\\testStream\\0\\student.data";
        try(DataOutputStream dos=new DataOutputStream(new FileOutputStream(fileName)))
        {
        	Student stu1=new Student(1,"zhang",13,80);
        	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();
		}
    }
}

我的总结

一、 使用DataOutputStream与FileOutputStream将Student对象写入二进制文件student.data

  1. 二进制文件与文本文件的区别
  • 二进制文件可以存储int/double/char..等基本数据类型,文本文件只能存储char型变量。因此文本文件在读取或存储过程中常需要用到类型转换(类似parseInt)

2.try...catch...finally注意事项

  • catch多个异常时要注意异常写的先后顺序,总体来说越大的(父类)异常要放越后面。可以直接使用eclipse的提示功能直接自己生成异常,方便又不会出错。

3.使用try..with...resouces关闭资源

  • 是jdk8新的语法,可以直接在try(........)的括号中定义最后要关闭的资源,在运行结束后会自动关闭,不需要传统地在finally中关闭资源。用法详见上面代码块。

1. 字符流与文本文件

我的代码

任务1

String fileName="d:\\testStream\\1\\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);

任务2

public static List<Student> readStudents(String fileName)
	{
		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();
		}
		return studentList;
	}

任务3

String fileName="d:\\testStream\\1\\Students.txt";
try(
			FileOutputStream fos=new FileOutputStream(fileName,true);
			OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8");
			PrintWriter pw=new PrintWriter(osw))
		{
			pw.println();
			pw.print("4 一一 13 80");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

任务4

String fileName1="d:\\testStream\\1\\Students.dat";
try(
			FileOutputStream fos=new FileOutputStream(fileName1);
			ObjectOutputStream oos=new ObjectOutputStream(fos))
		{
			Student ts=new Student(5,"asd",14,60);
			oos.writeObject(ts);
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try(
			FileInputStream fis=new FileInputStream(fileName1);
			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();
		}

我的总结

  • 在任务1、2、3中,程序生成的txt文件是指定的UTF-8编码。后续如果人为地通过系统自带的文本文档打开Students.txt并进行保存,该文本会变成UTF-8-BOM编码。这样程序再次运行时就会报错,因为指定的UTF-8跟文件实际上的UTF-8-BOM是不一样的,这个问题困扰了我一段时间,目前我的解决方法是两个:不人为保存,或者需要人为保存时用notepad++。
  • 任务3中一开始PrintWriter会直接覆盖原文件,通过查阅资料,在构造FileOutputStream时多传一个true就可以了。
  • 任务4中,一开始是让对象流写在txt中,后面发现会发生乱码。通过查阅资料知道writeObject()的作用是让实例以文件的形式保存在磁盘上,而这个文件是用二进制的形式写的,所以就让对象流的处理文件是bat格式,就没错了。

2.缓冲流

我的代码


public class Main2 {
	public static void main(String[] args) {
		String fileName="d:\\testStream\\2\\test.txt";
		try (PrintWriter pw = new PrintWriter(fileName);)
		{
			Random random=new Random();
			random.setSeed(100);
			double sum=0,aver;
		    for (int i = 0; i < 1000_0000; i++) {
		    	int r=random.nextInt(10);
		    	sum+=r;
		        pw.println(r);
		    }
		    aver=sum/1000_0000;
		    System.out.format("%.5f", aver);
		    
		} catch (FileNotFoundException e) {
		    e.printStackTrace();
		}
	}
}

JUNIT测试部分


import static org.junit.jupiter.api.Assertions.*;

import java.io.*;
import java.util.*;
import org.junit.jupiter.api.Test;

class testBufferedReader {
	String fileName="d:\\testStream\\2\\test.txt";
	@Test
	void testScanner() {
		try (	FileInputStream fis = new FileInputStream(fileName);
				Scanner sc=new Scanner(fis))
		{
			while(sc.hasNextInt())
			{
				sc.nextInt();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}finally
		{
			System.out.println("sc end");
		}
	}
	@Test
	void testBufferedReader() {
		try (	FileReader fr = new FileReader(fileName);
				BufferedReader br=new BufferedReader(fr))
		{
			String line=null;
			while((line=br.readLine())!=null)
			{
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}finally
		{
			System.out.println("br end");
		}
	}
}

我的总结

  • 生成随机数平时用的少,每次需要用时都得先找点资料,要尽量记住常见的用法。
  • 在将随机数写入文件时,如果用的是print而不是println,文本大小会是println的三分一(1000_0000字节和3000_0000字节),因为一个回车2字节,没有写回车的话junit跑出来的结果Scanner和BufferedReader的时间是差不多的,而写了回车时间差距就很大。
  • JUNIT中要测试的方法前要加上@Test

3.字节流之对象流

我的代码

public static void writeStudent(List<Student> stuList)
	{
		String fileName="d:\\testStream\\3\\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时一行一个Student对象地读取,而是直接读出一个集合或数组

5.文件操作

我的代码

递归


public class Main5 {

	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类可以互相转换,Path是File的升级。
  • Paths类可以直接获得Path对象,不需要new Path。

6.正则表达式

我的代码

任务1


public class Main6 {

	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();
	}
}

任务2-匹配数字字符串

package javalearning;

import java.io.*;
import java.net.*;
import java.util.regex.*;

/**
 * This program displays all URLs in a web page by matching a regular expression that describes the
 * <a href=...> HTML tag. Start the program as <br>
 * java HrefMatch URL
 * @version 1.01 2004-06-04
 * @author Cay Horstmann
 */
public class HrefMatch
{
   public static void main(String[] args)
   {
      try
      {
         // get URL string from command line or use default
        /* String urlString;
         if (args.length > 0) urlString = args[0];
         else urlString = "http://java.sun.com";*/
    	 String fileName="D:\\testStream\\6\\集美大学-计算机工程学院.htm";
         // open reader for URL
        //InputStreamReader in = new InputStreamReader(new URL(urlString).openStream());
    	 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();
      }
   }
}

任务2-匹配图片字符串(仅展示部分,其余同数字字符串匹配)

         String patternImgString = "img\\s[a-zA-Z]+=\".*.(gif|png|jpg|jpeg)\"";
         Pattern pattern = Pattern.compile(patternImgString, Pattern.CASE_INSENSITIVE);
         Matcher matcher = pattern.matcher(input);

我的总结

  • 要熟练匹配字符串平时就要多写正则表达式,匹配图片字符串的patternImgString写了一段时间,最后还是没有做到完美的匹配(特殊情况会匹配不准确)
posted @ 2019-11-24 22:06  damao_33  阅读(1069)  评论(0编辑  收藏  举报