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写了一段时间,最后还是没有做到完美的匹配(特殊情况会匹配不准确)
  • 相关阅读:
    HDU 1813 Escape from Tetris
    BZOJ 2276 Temperature
    BZOJ 4499 线性函数
    BZOJ 3131 淘金
    HDU 5738 Eureka
    POJ 2409 Let it Bead
    POJ 1286 Necklace of Beads
    POJ 1696 Space Ant
    Fox And Jumping
    Recover the String
  • 原文地址:https://www.cnblogs.com/damao33/p/11924697.html
Copyright © 2011-2022 走看看