zoukankan      html  css  js  c++  java
  • 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写了一段时间,最后还是没有做到完美的匹配(特殊情况会匹配不准确)
  • 相关阅读:
    第一部分 题目要求
    完全卸载oracle
    zabbix的面试题目总结
    性能优化之MySQL调优篇
    select与epoll、apache与nginx实现原理对比
    深度优化LNMP之PHP
    深度优化LNMP之Nginx (转)
    git常用命令
    ansible 安装与卸载软件
    java8两个List集合取交集、并集、差集、去重并集
  • 原文地址:https://www.cnblogs.com/damao33/p/11924697.html
Copyright © 2011-2022 走看看