zoukankan      html  css  js  c++  java
  • Java第09次实验(IO流)

    0. 字节流与二进制文件

    1. 使用DataOutputStream与FileOutputStream将Student对象写入二进制文件student.data
      • 二进制文件与文本文件的区别
      • try...catch...finally注意事项
      • 使用try..with...resouces关闭资源
    2. 使用DataInputStream与FileInputStream从student.data中读取学生信息并组装成对象

    我的代码

      1 class Student {
      2     private int id;
      3     private String name;
      4     private int age;
      5     private double grade;    
      6     public Student(){
      7         
      8     }
      9     public Student(int id, String name, int age, double grade) {
     10         this.id = id;
     11         this.setName(name);
     12         this.setAge(age);
     13         this.setGrade(grade);
     14     }
     15     public int getId() {
     16         return id;
     17     }
     18     public void setId(int id) {
     19         this.id = id;
     20     }
     21     public String getName() {
     22         return name;
     23     }
     24     public void setName(String name) {
     25         if (name.length()>10){
     26             throw new IllegalArgumentException("name's length should <=10 "+name.length());
     27         }
     28         this.name = name;
     29     }
     30     public int getAge() {
     31         return age;
     32     }
     33     public void setAge(int age) {
     34         if (age<=0){
     35             throw new IllegalArgumentException("age should >0 "+age);
     36         }
     37         this.age = age;
     38     }
     39     public double getGrade() {
     40         return grade;
     41     }
     42     public void setGrade(double grade) {
     43         if (grade<0 || grade >100){
     44             throw new IllegalArgumentException("grade should be in [0,100] "+grade);
     45         }
     46         this.grade = grade;
     47     }
     48     @Override
     49     public String toString() {
     50         return "Student [id=" + id + ", name=" + name + ", age=" + age + ", grade=" + grade + "]";
     51     }
     52     
     53 }
     54  public class Main {
     55         public static void main(String[] args)
     56         {
     57             
     58             String fileName="d:\student.data";
     59             try(DataOutputStream dos=new DataOutputStream(new FileOutputStream(fileName)))
     60             {
     61                 Student[] stu=new Student[3];
     62                 stu[0]=new Student(1,"zhangsan",19,65.0);
     63                 stu[1]=new Student(2,"lisi",19,75.0);
     64                 stu[2]=new Student(3,"wangwu",20,85.0);
     65                 for(Student stu1:stu) {
     66                     dos.writeInt(stu1.getId());
     67                     dos.writeUTF(stu1.getName());
     68                     dos.writeInt(stu1.getAge());
     69                     dos.writeDouble(stu1.getGrade());
     70                 }
     71                 
     72             } catch (FileNotFoundException e) {
     73                 // TODO Auto-generated catch block
     74                 e.printStackTrace();
     75                 System.out.println("1");
     76             } catch (IOException e) {
     77                 // TODO Auto-generated catch block
     78                 e.printStackTrace();
     79                 System.out.println("2");
     80             }
     81             try(DataInputStream dis=new DataInputStream(new FileInputStream(fileName)))
     82             {
     83                 while(dis!=null) {
     84                     int id=dis.readInt();
     85                     String name=dis.readUTF();
     86                     int age=dis.readInt();
     87                     double grade=dis.readDouble();
     88                     Student stu=new Student(id,name,age,grade);
     89                     System.out.println(stu);
     90                 }
     91                 
     92                 
     93             } catch (FileNotFoundException e) {
     94                 // TODO Auto-generated catch block
     95                 e.printStackTrace();
     96                 System.out.println("3");
     97             } catch (IOException e) {
     98                 // TODO Auto-generated catch block
     99                 e.printStackTrace();
    100                 System.out.println("4");
    101             }
    102             
    103         }

    我的总结

    在读取文件数据时while循环会报错,加入测试点后发现while循环多读了一次,

    后将while(dis!=null)改成while(dis.available()!=0),问题解决

    1. 字符流与文本文件:使用 PrintWriter(写),BufferedReader(读)

    任务:

    1. 使用BufferedReader从编码为UTF-8的文本文件中读出学生信息,并组装成对象然后输出。
      • 中文乱码问题(FileReader使用系统默认编码方式读取文件,会产生乱码,可使用InputStreamReader解决)
      • String的split方法使用\s+可以使用多个空格作为分隔符。
      • 进阶:修改Students.txt文件,在正确的数据行中间增加一些错误行(如,每行只有3个数据,或者应该是数字的地方放入其他字符),修改自己的程序,让起可以处理出错的行(报错但可以继续运行)。
    2. 编写public static ListreadStudents(String fileName);从fileName指定的文本文件中读取所有学生,并将其放入到一个List中
    3. 使用PrintWriter将Student对象写入文本文件,基础代码见后。注意:缓冲区问题。
    4. 使用ObjectInputStream/ObjectOutputStream读写学生对象。

    我的代码

    1.

     1  public class Main {
     2         public static void main(String[] args) throws IOException
     3         {
     4             String FileName="D:\TSBrowserDownloads\Students.txt";
     5             BufferedReader br = null;
     6             try {
     7                 br = new BufferedReader(new InputStreamReader(new FileInputStream(FileName),"UTF-8"));
     8                 String line = null;
     9                 while((line=br.readLine())!=null)
    10                     System.out.println(line);
    11             } finally{
    12                 if (br!=null){
    13                     br.close();
    14                 }
    15             }
    16         }
    17 
    18     }

    我的总结

    默认方法打开读取会产生乱码

    将模式读取方式改成"UTF-8"后显示正常

    2.

     1 public static void ListreadStudents(String fileName){
     2             ArrayList<Student> StudentList=new ArrayList<Student>();
     3             BufferedReader br = null;
     4             try {
     5                 br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName),"UTF-8"));
     6                 while(br!=null) {
     7                     String line=br.readLine();
     8                     String[] stu=line.split("\s+");
     9                     int id=Integer.parseInt(stu[0]);
    10                     String name=stu[1];
    11                     int age=Integer.parseInt(stu[2]);
    12                     double grade=Double.parseDouble(stu[3]);
    13                     Student Stu=new Student(id,name,age,grade);
    14                     StudentList.add(Stu);          
    15                 }                
    16             } finally{
    17                 if (br!=null){
    18                     br.close();
    19                 }
    20             }
    21 }

    实验调试

    刚开始本来想用和DataInputStream一样直接读,发现BufferedReader只用read和ReadLine方法,得用实验提到的"\s+"的方法将读到的一整行用分隔符来分开,再用类型转换来读。

    3.

    2             String FileName="D:\TSBrowserDownloads\Students.txt";
    3             PrintWriter pw=new PrintWriter(new OutputStreamWriter(new FileOutputStream(FileName,true),"UTF-8"));
    4             pw.print("4 陈六 21 93");
    5             pw.close();

    我的总结

    正确写入文件

    4.

     1         String FileName="D:\TSBrowserDownloads\student.dat";
     2             try(
     3                     FileOutputStream fos=new FileOutputStream(FileName);
     4                     ObjectOutputStream oos=new ObjectOutputStream(fos))
     5                 {
     6                     Student ts=new Student(5,"asd",14,60);
     7                     oos.writeObject(ts);
     8                 }
     9                 catch (Exception e) {
    10                     // TODO Auto-generated catch block
    11                     e.printStackTrace();
    12                 }
    13                 try(
    14                     FileInputStream fis=new FileInputStream(FileName);
    15                     ObjectInputStream ois=new ObjectInputStream(fis))
    16                 {
    17                     Student newStudent =(Student)ois.readObject();
    18                     System.out.println(newStudent);
    19                 } catch (IOException e) {
    20                     // TODO Auto-generated catch block
    21                     e.printStackTrace();
    22                 } catch (ClassNotFoundException e) {
    23                     // TODO Auto-generated catch block
    24                     e.printStackTrace();
    25                 }

    2. 缓冲流(结合使用JUint进行测试)

    使用PrintWriter往文件里写入1千万行随机整数,范围在[0,10]。随机数种子设置为100.
    然后从文件将每行读取出来转换成整数后相加。然后依次输出“个数 和 平均值(保留5位小数)”。
    对比使用BufferedReader与使用Scanner从该文件中读取数据(只读取,不输出),使用哪种方法快?

      • 使用junit对比BufferedReaderScanner读文件的效率
      • 格式化输出:System.out.format。
      • 要使用Scanner的hasNextXXX方法来判断是否到文件尾,否则会抛异常。
      • Scanner的asNextXXX方法应与相对应的nextXXX方法配合使用,否则容易出。
      • 请删除fail("Not yet implemented");;并且在需要测试的方法上使用@Test进行标注。

    写入文件代码

     1 String FILENAME = "test.txt";    
     2         double sum=0,aver;
     3         PrintWriter pw=null;
     4         try {
     5             pw = new PrintWriter(FILENAME);
     6             for(int i = 0;i<10000000;i++){//写入1千万行
     7             int r=new Random().nextInt(10);
     8             sum+=r;
     9             pw.println(r);
    10             //System.out.println(r);
    11         }
    12         } catch (FileNotFoundException e) {
    13             e.printStackTrace();
    14         }finally{
    15             pw.close();
    16         }
    17         aver=sum/10000000;
    18         System.out.format("%.5f", aver);
    19     }

    使用JUint的代码

     1         public class test {
     2     @Test
     3         public void test() {
     4         String FILENAME = "test.txt";
     5         long begin = System.currentTimeMillis();
     6         Scanner scanner=null;
     7         try {
     8             scanner = new Scanner(new File(FILENAME));
     9             while(scanner.hasNextLine()){//只是读出每一行,不做任何处理
    10                 scanner.nextLine();
    11             }
    12         } catch (FileNotFoundException e) {
    13             e.printStackTrace();
    14         }finally{
    15             scanner.close();
    16         }
    17         long end = System.currentTimeMillis();
    18         System.out.println("last "+(end-begin));
    19         System.out.println("read using Scanner done");
    20     }
    21     @Test
    22     public void Bufftest() {
    23         String FILENAME = "test.txt";
    24         long begin = System.currentTimeMillis();
    25         BufferedReader br = null;
    26         try {
    27              br = new BufferedReader(new FileReader(new File(FILENAME)));
    28             while(br.readLine()!=null){};//只是读出,不进行任何处理
    29         } catch (FileNotFoundException e) {
    30             e.printStackTrace();
    31         } catch (IOException e) {
    32             e.printStackTrace();
    33         }finally{
    34             try {
    35                 br.close();
    36             } catch (IOException e) {
    37                 e.printStackTrace();
    38             }
    39         }
    40         long end = System.currentTimeMillis();
    41         System.out.println("last "+(end-begin));
    42         System.out.println("read using BufferedReader done");
    43     }
    44 }

    我的总结

    可以明显对比出缓冲流BufferedReader的方法要比Scanner的方法快很多

     不使用JUint也可以在循环开始前后定义时间变量,最后相减也能得到运行所用时间

    第2次实验

    3. 字节流之对象流

    结合使用ObjectOutputStream、ObjectInputStream与FileInputStream、FileOuputStream实现对Student对象的读写。
    编写如下两个方法:

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

     我的代码

     1 public static void writeStudent(List<Student> stuList)
     2     {
     3         String fileName="D:\Student.dat";
     4         try (   FileOutputStream fos=new FileOutputStream(fileName);
     5                 ObjectOutputStream ois=new ObjectOutputStream(fos))
     6         {
     7             ois.writeObject(stuList);
     8             
     9         } 
    10         catch (FileNotFoundException e) {
    11             // TODO Auto-generated catch block
    12             e.printStackTrace();
    13         } catch (IOException e1) {
    14             // TODO Auto-generated catch block
    15             e1.printStackTrace();
    16         }
    17     }
    18 public static List<Student> readStudents(String fileName)
    19     {
    20         List<Student> stuList=new ArrayList<>();
    21         try (   FileInputStream fis=new FileInputStream(fileName);
    22                 ObjectInputStream ois=new ObjectInputStream(fis))
    23         {
    24             stuList=(List<Student>)ois.readObject();
    25         } 
    26         catch (FileNotFoundException e) {
    27             // TODO Auto-generated catch block
    28             e.printStackTrace();
    29         } catch (IOException e1) {
    30             // TODO Auto-generated catch block
    31             e1.printStackTrace();
    32         } catch (ClassNotFoundException e) {
    33             // TODO Auto-generated catch block
    34             e.printStackTrace();
    35         }
    36         return stuList;
    37     }   

    5. 文件操作

    编写一个程序,可以根据指定目录和文件名,搜索该目录及子目录下的所有文件,如果没有找到指定文件名,则显示无匹配,否则将所有找到的文件名与文件夹名显示出来。

      1. 编写public static void findFile(Path dir,String fileName)方法.
        以dir指定的路径为根目录,在其目录与子目录下查找所有和filename
        相同的文件名,一旦找到就马上输出到控制台。

    我的代码

     1 if (args.length == 0) args = new String[] { ".." };
     2       try
     3       {
     4          File pathName = new File(args[0]);
     5          String[] fileNames = pathName.list();
     6 
     7          // enumerate all files in the directory
     8          for (int i = 0; i < fileNames.length; i++)
     9          {
    10             File f = new File(pathName.getPath(), fileNames[i]);
    11 
    12             // if the file is again a directory, call the main method recursively
    13             if (f.isDirectory())
    14             {
    15                 if(f.getName().contains(fileName)) {
    16                     System.out.println(f.getCanonicalPath());
    17                     main(new String[] { f.getPath() });
    18                 }          
    19             }
    20          }
    21       }
    22       catch (IOException e)
    23       {
    24          e.printStackTrace();
    25       }

    我的总结

    用了参考代码稍加修改,若文件名字包含fileName,则输出该文件的路径

    6. 正则表达式

    1. 如何判断一个给定的字符串是否是10进制数字格式?尝试编程进行验证。
    2. 修改HrefMatch.java
      • 尝试匹配网页中的数字字符串
      • 尝试匹配网页中的图片字符串

    1.

     1  Scanner sc=new Scanner(System.in);
     2             Pattern pattern=Pattern.compile("^-?[0-9]\d*(\.\d+)?$");
     3             Matcher matcher=null;
     4             while(sc.hasNext())
     5             {
     6                 String str=sc.next();
     7                 matcher=pattern.matcher(str);
     8                 System.out.println(matcher.matches());
     9             }
    10             sc.close();

    2.

     1 try
     2       {
     3          // get URL string from command line or use default
     4          String urlString;
     5          if (args.length > 0) urlString = args[0];
     6          else urlString = "http://cec.jmu.edu.cn";
     7 
     8          // open reader for URL
     9         InputStreamReader in = new InputStreamReader(new URL(urlString).openStream());
    10     //InputStreamReader in = new InputStreamReader(new FileInputStream("集美大学-计算机工程学院.htm"));
    11          // read contents into string builder
    12          StringBuilder input = new StringBuilder();
    13          int ch;
    14          while ((ch = in.read()) != -1)
    15             input.append((char) ch);
    16 
    17          // search for all occurrences of pattern
    18          String patternString = "<a\s+href\s*=\s*("[^"]*"|[^\s>]*)\s*>";
    19      String patternImgString = "[+-]?[0-9]+";
    20      //String patternString = "[u4e00-u9fa5]";     //匹配文档中的所有中文
    21          Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
    22          Matcher matcher = pattern.matcher(input);
    23 
    24          while (matcher.find())
    25          {
    26             int start = matcher.start();
    27             int end = matcher.end();
    28             String match = input.substring(start, end);
    29             System.out.println(match);
    30          }
    31       }
    32       catch (IOException e)
    33       {
    34          e.printStackTrace();
    35       }
    36       catch (PatternSyntaxException e)
    37       {
    38          e.printStackTrace();
    39       }

    总结:这次实验内容较多,花费了大量的时间,总的来说IO流是java中很重要的一部分,涉及面很广,还会和今后的网络编程牵扯关系,应该好好学。正值表达式的内容较难理解

  • 相关阅读:
    [问题2015S13] 复旦高等代数 II(14级)每周一题(第十四教学周)
    [问题2015S12] 复旦高等代数 II(14级)每周一题(第十三教学周)
    [问题2015S11] 复旦高等代数 II(14级)每周一题(第十二教学周)
    [问题2015S10] 复旦高等代数 II(14级)每周一题(第十一教学周)
    [问题2015S09] 复旦高等代数 II(14级)每周一题(第十教学周)
    [问题2015S08] 复旦高等代数 II(14级)每周一题(第九教学周)
    @JsonFormat与@DateTimeFormat注解的使用
    intellij idea 重命名或复制一个项目(不用重启)
    PageHelper中默认PageInfo成员变量
    图片的base64编码
  • 原文地址:https://www.cnblogs.com/cxxxxxx/p/11934648.html
Copyright © 2011-2022 走看看