Java第09次实验(流与文件)
第一次实验
0. 字节流与二进制文件
1.使用DataOutputStream与FileOutputStream将Student对象写入二进制文件student.data
- 二进制文件与文本文件的区别
 - try...catch...finally注意事项
 
2.使用try..with...resouces关闭资源
3.使用DataInputStream与FileInputStream从student.data中读取学生信息并组装成对象
我的代码
package homework;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
class Student {
       private int id;
       private String name;
       private int age;
       private double grade;
       public Student(){
       }
       public Student(int id, String name, int age, double grade) {
          this.id = id;
          this.setName(name);
          this.setAge(age);
          this.setGrade(grade);
      }
      public int getId() {
          return id;
      }
      public void setId(int id) {
          this.id = id;
      }
      public String getName() {
          return name;
      }
      public void setName(String name) {
          if (name.length()>10){
              throw new IllegalArgumentException("name's length should <=10 "+name.length());
          }
          this.name = name;
      }
      public int getAge() {
          return age;
      }
      public void setAge(int age) {
          if (age<=0){
              throw new IllegalArgumentException("age should >0 "+age);
          }
          this.age = age;
      }
      public double getGrade() {
          return grade;
      }
      public void setGrade(double grade) {
          if (grade<0 || grade >100){
              throw new IllegalArgumentException("grade should be in [0,100] "+grade);
          }
          this.grade = grade;
      }
      @Override
      public String toString() {
          return "Student [id=" + id + ", name=" + name + ", age=" + age + ", grade=" + grade + "]";
      }
  }
   public class Main {
          public static void main(String[] args)
          {
              String fileName="d:\\student.data";
              try(DataOutputStream dos=new DataOutputStream(new FileOutputStream(fileName)))
              {
                  Student[] stu=new Student[3];
                  stu[0]=new Student(1,"zhangsan",19,65.0);
                  stu[1]=new Student(2,"lisi",19,75.0);
                  stu[2]=new Student(3,"wangwu",20,85.0);
                  for(Student stu1:stu) {
                      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)))
              {
                  while(dis!=null) {
                      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();
             }
        }
   }
我的总结
二进制文件与文本文件的区别:
广义上的二进制文件包括文本文件,这里讨论的是狭义上的二进制文件与文本文件的比较:
1. 能存储的数据类型不同:文本文件只能存储char型字符变量。二进制文件可以存储char/int/short/long/float/……各种变量值。
2. 每条数据的长度不同:文本文件每条数据通常是固定长度的。以ASCII为例,每条数据(每个字符)都是1个字节。二进制文件每条数据不固定。如short占两个字节,int占四个字节,float占8个字节。
3. 读取的软件不同:文本文件编辑器就可以读写。比如记事本、NotePad++、Vim等。二进制文件需要特别的解码器。比如bmp文件需要图像查看器,rmvb需要播放器。
4. 操作系统对换行符('\n')的处理不同(不重要):文本文件,操作系统会对'\n'进行一些隐式变换,因此文本文件直接跨平台使用会出问题。在Windows下,写入'\n'时,操作系统会隐式的将'\n'转换为"\r\n",再写入到文件中;读的时候,会把“\r\n”隐式转化为'\n',再读到变量中。在Linux下,写入'\n'时,操作系统不做隐式变换。
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读写学生对象。
我的代码
package homework;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
          public static void main(String[] args) throws IOException
          {
              String FileName="D:\\TSBrowserDownloads\\Students.txt";
              BufferedReader br = null;
              try {
                  br = new BufferedReader(new InputStreamReader(new FileInputStream(FileName),"UTF-8"));
                  String line = null;
                  while((line=br.readLine())!=null)
                     System.out.println(line);
             } finally{
                 if (br!=null){
                     br.close();
                 }
             }
         }
     }
我的总结
1.在编译过程中总是会出现很多错误,首先是头文件的问题,还有就是一些错误的提示,不知道怎么去改正,这方面学习的不好,通过同学才明白。
2.还有就是做题中会用到的一些知识点。
2. 缓冲流(结合使用JUint进行测试)
使用PrintWriter往文件里写入1千万行随机整数,范围在[0,10]。随机数种子设置为100.
然后从文件将每行读取出来转换成整数后相加。然后依次输出“个数 和 平均值(保留5位小数)”。
对比使用BufferedReader与使用Scanner从该文件中读取数据(只读取,不输出),使用哪种方法快?
- 使用junit对比BufferedReader与Scanner读文件的效率
 - 格式化输出:System.out.format。
 - 要使用Scanner的hasNextXXX方法来判断是否到文件尾,否则会抛异常。
 - Scanner的asNextXXX方法应与相对应的nextXXX方法配合使用,否则容易出。
 - 请删除fail("Not yet implemented");;并且在需要测试的方法上使用@Test进行标注。
 
我的代码
 package homework;
public class test {
     @Test
          public void test() {
          String FILENAME = "test.txt";
          long begin = System.currentTimeMillis();
          Scanner scanner=null;
          try {
              scanner = new Scanner(new File(FILENAME));
              while(scanner.hasNextLine()){//只是读出每一行,不做任何处理
                 scanner.nextLine();
             }
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         }finally{
             scanner.close();
         }
       long end = System.currentTimeMillis();
        System.out.println("last "+(end-begin));
         System.out.println("read using Scanner done");
     }
     @Test
     public void Bufftest() {
         String FILENAME = "test.txt";
         long begin = System.currentTimeMillis();
         BufferedReader br = null;
         try {
              br = new BufferedReader(new FileReader(new File(FILENAME)));
             while(br.readLine()!=null){};//只是读出,不进行任何处理
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                 br.close();
             } catch (IOException e) {
                 e.printStackTrace();           }
        }
        long end = System.currentTimeMillis();
         System.out.println("last "+(end-begin));
         System.out.println("read using BufferedReader done");
     }
}
我的总结
总体来说使用Scanner读取文本文件要比用BufferedReader更容易,而且,Scanner具有比BufferedReader更多的方法。
思考题:
为什么以下代码生成的文件大小是0,而只有当count=16384(两倍的默认缓冲区大小)才可以真正写入到文件?
String fileName = "d:/Test.data";
int count = 16383;
PrintWriter pw = null;
try {
pw = new PrintWriter(fileName);
for (int i = 0; i < count; i++) {
    pw.print(1);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
//pw.close();
}
答:
第二次实验
3. 字节流之对象流
结合使用ObjectOutputStream、ObjectInputStream与FileInputStream、FileOuputStream实现对Student对象的读写。
编写如下两个方法:
- public static void writeStudent(List stuList)
 - public static List readStudents(String fileName)
进阶:
使用wxMEdit打开ObjectOutputStream所生成的文件格式,尝试修改文件,并通过代码读取文件进行验证。 
我的代码
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     }
我的总结
1.ObjectOutputStream的使用
- ObjectOutputStream是一个高级流, 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
2.ObjectInputStream的使用
- ObjectInputStream也是一个高级流,对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
3.ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。ObjectOutputStream用于序列化对象,ObjectInputStream 用于恢复那些以前序列化的对象(反序列化)。其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参。
4. 选做:RandomAccessFile
像操作数组一样操作文件内容。
将以上的对大量Student对象的读写使用RandomAceessFile。
特别考核:你觉得使用RandomAccessFile读写文件与使用字节流、字符流、缓冲流相比较各有何优缺点。
我的代码
我的总结
5. 文件操作
1.编写一个程序,可以根据指定目录和文件名,搜索该目录及子目录下的所有文件,如果没有找到指定文件名,则显示无匹配,否则将所有找到的文件名与文件夹名显示出来。
编写public static void findFile(Path dir,String fileName)方法.
以dir指定的路径为根目录,在其目录与子目录下查找所有和filename
相同的文件名,一旦找到就马上输出到控制台。
提示:
1.使用递归或队列。建议使用队列完成。
2.使用图形界面:
GUI下可使用JFileChooser控件实现选取目录。控制台下手动指定目录名。
参考代码(参考代码 目录中):一个简单的包括菜单的GUI小程序.rar(包含JFileChooser的用法)
FindDirectories.java (用于查找文件)
进阶(选做):
自己编写的文件搜索方法基本上有很大缺陷,如不能正确处理符号链接。
考核点:查询资料,尝试使用Files.walkFileTree方法进行文件搜索。
我的代码
if (args.length == 0) args = new String[] { ".." };
       try
        {
           File pathName = new File(args[0]);
           String[] fileNames = pathName.list();
           // enumerate all files in the directory
          for (int i = 0; i < fileNames.length; i++)
           {
             File f = new File(pathName.getPath(), fileNames[i]);
             // if the file is again a directory, call the main method recursively             if (f.isDirectory())
             {
                 if(f.getName().contains(fileName)) {
                     System.out.println(f.getCanonicalPath());
                     main(new String[] { f.getPath() });
                 }
             }
          }
       }
       catch (IOException e)
       {
          e.printStackTrace();
       }
我的总结
1,Files.walkFileTree的原理介绍
原型:static Path Files.walkFileTree(Path start, FileVisitor<? super Path> visitor);
ii. 表示从start代表的节点开始遍历文件系统;
iii. 其中visitor是遍历过程中的行为控制器;
4) 遍历行为控制器——FileVisitor:
i. 它是一个接口,里面定义了4个方法用来指定当你访问一个节点之前、之中、之后、失败时应该采取什么行动;
6. 正则表达式
1.如何判断一个给定的字符串是否是10进制数字格式?尝试编程进行验证。
2.修改HrefMatch.java
- 尝试匹配网页中的数字字符串
 - 尝试匹配网页中的图片字符串
1、2为一考核点。 
我的代码
test
        {
           // get URL string from command line or use default
           String urlString;
           if (args.length > 0) urlString = args[0];
          else urlString = "http://cec.jmu.edu.cn";
           // open reader for URL
          InputStreamReader in = new InputStreamReader(new URL(urlString).openStream());
     //InputStreamReader in = new InputStreamReader(new FileInputStream("集美大学-计算机工程学院.htm"));
          // read contents into string builder
          StringBuilder input = new StringBuilder();
          int ch;
          while ((ch = in.read()) != -1)
             input.append((char) ch);
          // search for all occurrences of pattern
          String patternString = "<a\\s+href\\s*=\\s*(\"[^\"]*\"|[^\\s>]*)\\s*>";
      String patternImgString = "[+-]?[0-9]+";
     //String patternString = "[\u4e00-\u9fa5]";     //匹配文档中的所有中文
          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();
       }
我的总结
正则表达式是什么:正则表达式(regular expression)是一个描述字符模式的对象。JavaScript的RegExp类表示正则表达式,String和RegExp都定义了方法。
												
											Java第09次实验(流与文件)的更多相关文章
- JAVA第09次实验(IO流)
		
JAVA第09次实验(IO流) 0.字节流与二进制文件 我的代码 import java.io.DataInputStream; import java.io.DataOutputStream; im ...
 - Java第09次实验(IO流)
		
参考资料 本次作业参考文件 正则表达式参考资料 第1次实验 0. 验证 使用FileOutputStream写字节.(二进制文件与文本文件.try...catch...finally注意事项) 使用D ...
 - JAVA中的I/O流以及文件操作
		
一 JAVA语言中主要通过流来完成IO操作. 流:计算机的输入输出之间流动的数据序列,也是类的对象.java中的流方式就像是建立在数据交换源和目的之间的一条通信路径. 数据源:计算机中的数据源是指可以 ...
 - java使用字节流和字符流实现文件复制
		
大家在Java开发中都会遇到文件复制的文件,众所周知,需要通过文件输入输出流实现. 那究竟该怎么做那,话不多说,直接上代码: 一,使用字节流复制文件 public class FileByteCopy ...
 - Java中字节流和字符流复制文件
		
字节流和字符流复制文件的过程: 1.建立两个流对象 绑定数据源和目的地 2.遍历出需复制的文件写入复制过后的新文件中(只不过是遍历的时候是区分字节和字符的) 3.访问结束后关闭资源 字节流复制文件: ...
 - Java基础教程:IO流与文件基础
		
Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...
 - Java第09次实验(IO流)-实验报告
		
0. 字节流与二进制文件 使用DataOutputStream与FileOutputStream将Student对象写入二进制文件student.data 二进制文件与文本文件的区别 try...ca ...
 - Java第09次实验(IO流)--实验报告
		
0.字节流与二进制文件 我的代码 用DataOutputStream和FileOutputStream将Student对象写入二进制文件student.data package test; impor ...
 - java学习笔记16--I/O流和文件
		
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input Output)流 IO流用来处理 ...
 
随机推荐
- luogu P3620 [APIO/CTSC 2007]数据备份
			
luogu 首先如果一条线不是了连接的相邻两个位置一定不优,把它拆成若干连接相邻位置的线.所以现在问题是有\(n\)个物品,选\(k\)个,要求选的位置不能相邻,求最小总和 如果没有选的位置不能相邻这 ...
 - Redis从入门到高可用,分布式实践
			
redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...
 - snappy-java两种压缩方式的区别
			
1.Snappy-java项目地址 https://github.com/xerial/snappy-java 2.Snappy-java两种压缩方式 使用Snappy.compress进行压缩 St ...
 - Axure(二)
			
回顾1.Axure 动态面板 图片转换 画面滚动2.使用元件 --> page box 盒子 width height ...
 - Django框架——基础之视图系统(View.py)
			
Django框架之View.py(视图文件) 1. 视图简介 视图层是Django处理请求的核心代码层,我们大多数Python代码都集中在这一层面. 它对外接收用户请求,对内调度模型层和模版层,统合数 ...
 - ansible的基本学习-安装和简单的配置测试
			
当下有许多的运维自动化工具(配置管理),例如:ansible.saltstack.puppet.fabric等 ansible 是一种集成it系统的配置管理.应用部署.执行特定任务的开源平台,是ans ...
 - 19、Firewalld防火墙
			
安全的考虑方向: 安全框架 OSI七层模型 硬件 机架上锁(机柜) 温度 硬件检查 网络 iptables/firewalld 仅允许公司的IP地址能连接服务器的22端口 公有云使用 安全组 系统 没 ...
 - nginx服务学习第一章
			
一.ubuntu系统安装nginx服务 # apt-get install nginx 二.nginx.config配置文件详解 配置文件结构: 全局块(全局变量) events{ } http{ h ...
 - Dubbo 04 服务化最佳实现流程
			
Dubbo 04 服务化最佳实践 分包 建议将服务接口.服务模型.服务异常等均放在 API 包中,因为服务模型和异常也是 API 的一部分,这样做也符合分包原则:重用发布等价原则(REP),共同重用原 ...
 - 使用IDEA搭建一个Spring + AOP (权限管理 ) + Spring MVC + Mybatis的Web项目 (零配置文件)
			
前言: 除了mybatis 不是零配置,有些还是有xml的配置文件在里面的. 注解是Spring的一个构建的一个重要手段,减少写配置文件,下面解释一下一些要用到的注解: @Configuration ...