201621123031 《Java程序设计》第12周学习总结
作业12-流与文件
1.本周学习总结
1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容。
在Java中的java.io包中定义了许多类专门负责处理各种方式的输入与输出。其中,所有输入流类都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类,而所有输出流类都是抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类。

1.输入流
InputStream类的层次结构

Reader类的层次结构

2.输出流
OutputStream类的层次结构

Writer类的层次结构

3.File类
File类是
java.io包中唯一代表磁盘文件本身的对象。File类定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件读写权限等。数据流可以将数据写入到文件中,文件也是数据流最常用的的数据媒体。
1.文件的创建
(1).New File(String pathname)
该构造方法通过将给定路径名字符串转换为抽象路径名来创建一个新的File实例
(2).new File(String parent,String child)
该构造方法根据定义的父路径和子路径字符串创建一个新的File对象
(3).new File(File f,String child)
该构造方法根据parent抽象路径名和child路径字符串创建一个新的File实例
2.获取文件信息
File类的常用方法
| 方法 | 返回值 | 说明 |
|---|---|---|
| getName() | String | 获取文件的名称 |
| canRead() | boolean | 判断文件是否是可读的 |
| canWrite() | boolean | 判断文件是否可被写入 |
| exits() | boolean | 判断文件是否存在 |
| length() | long | 获取文件长度 |
| getAbsoultePath() | String | 获取文件的绝对路径 |
| getParent() | String | 获取文件的父路径 |
| isFile() | boolean | 判断文件是否存在 |
| isDirectory() | boolean | 判断文件是否是一个目录 |
| isHidden() | boolean | 判断文件是否是隐藏文件 |
| lastModified() | long | 获取文件最后修改时间 |
2.面向系统综合设计-图书馆管理系统或购物车
使用流与文件改造你的图书馆管理系统或购物车。
2.1 简述如何使用流与文件改造你的系统。文件中数据的格式如何?
答:我在刚开始的时候先通过静态初始化块初始图书馆的数据然后将初始化后的图书数据使用对象流ObjectOutputStream写入文件Book.data进行保存,用户模块类似,然后在两个模块中各写一个保存修改后文件数据的方法用于存储操作过程中数据变化后的文件。用对象流写入文件是以十六进制保存的,因为对象流本来就是适合于网络之间的传输。
2.2 简述系统中文件读写部分使用了流与文件相关的什么接口与类?为什么要用这些接口与类?
用到了InputStream、OutputStream接口下的ObjectInputStream和ObjectOutputStream子类,还有文件类File,在对对象进行序列化的时候还用到了Serializable接口,使用对象流是为了可以将一个对象的完整信息都存入文件,如果只是普通的字节字符流则没办法做到这点,然后使用对象流写入或读取对象时,要保证对象时序列化的,这是为了保证能把对象写入文件,并且从文件中正确读到程序中,这时候就要用到Serializable接口来实现对象的序列化。
2.3 截图读写文件相关代码。关键行需要加注释。
初始化Library:


保存修改后的Library文件:

初始化用户模块:

保存修改过后的用户信息保存到文件中:

选做:3. 尝试为计算机学院网站设计一个搜索引擎系统(组队完成)
一开始可以只用控制台,不一定要用Web。
3.1 系统大概分为几部分,每个部分要完成什么功能?
3.2 系统的整个工作流程是什么。各个部分之间的关系是什么。可尝画图描述。
3.3 为了完成该系统需要什么方面的知识?
3.代码量统计
3.1 统计本周完成的代码量
需要将每周的代码统计情况融合到一张表中。
似乎达到了第一周设置的目标(◦˙▽˙◦)

| 周次 | 总代码量 | 新增代码量 | 总文件数 | 新增文件数 |
|---|---|---|---|---|
| 2 | 607 | 607 | 15 | 15 |
| 3 | 1642 | 1035 | 33 | 18 |
| 5 | 2044 | 402 | 42 | 9 |
| 6 | 2874 | 830 | 57 | 15 |
| 7 | 3161 | 287 | 63 | 6 |
| 8 | 4299 | 1138 | 72 | 9 |
| 9 | 4831 | 532 | 81 | 9 |
| 10 | 5475 | 644 | 93 | 12 |
| 11 | 5958 | 483 | 102 | 9 |
| 12 | 6819 | 861 | 116 | 14 |
| 13 | 7408 | 589 | 127 | 11 |
选做:4. 流与文件学习指导(底下的作业内容全部都是选做)
1. 字符流与文本文件:使用 PrintWriter(写),BufferedReader(读)
将Student对象(属性:int id, String name,int age,double grade)写入文件student.data、从文件读出显示。
1.1 生成的三个学生对象,使用PrintWriter的println方法写入student.txt,每行一个学生,学生的每个属性之间用|作为分隔。使用Scanner或者BufferedReader将student.txt的数据读出。(截图关键代码,出现学号)
三个Student对象:

writeStudent方法:

使用BufferedReader方法读取student.txt

控制台输出以及记事本内容:


1.2 生成文件大小多少(使用右键文件属性查看)?分析该文件大小


文件大小为48个字节,其中每个英文字符以及”|”占一个字节,每个中文字符占两个字节,换行符占两个字节,因此每一行为16个字节,三行总共48个字节。
1.3 如果调用PrintWriter的println方法,但在后面不close。文件大小是多少?为什么?
大小为0字节。
因为printWrite会将数据写到缓冲区内,在最后使用close进行关闭时,它会将缓冲区的内容送出来,所以当没有使用close进行关闭的时候,数据就会在缓冲区内丢失,因此如果在关闭前使用了flush方法将缓冲区的内容先送出来,还是可以将数据写入文件的。
2. 缓冲流
2.1 使用PrintWriter往文件里写入1千万行(随便什么内容都行),然后对比使用BufferedReader与使用Scanner从该文件中读取数据的速度(只读取,不输出),使用哪种方法快?截取测试源代码,出现学号。请详细分析原因?提示:可以使用junit4对比运行时间




可以看出使用BufferedReader读取文件更快,这是因为Scanner会对输入数据进行类解析,而BufferedReader只是简单地读取字符序列。并且BufferedReader相对于Scanner有更大的缓冲区,可以进行更少的输入输出操作,因此会更快一些。
2.2 将PrintWriter换成BufferedWriter,观察写入文件的速度是否有提升。记录两者的运行时间。试分析原因。



由上图可以看出,速度会有提升,这是因为BufferedWriter具有更大缓冲区的关系。
3. 字符编码
3.1 现有EncodeTest.txt 文件,包含一些中文,该文件使用UTF-8编码。使用FileReader与BufferedReader将EncodeTest.txt的文本读入并输出。是否有乱码?为什么会有乱码?如何解决?(截图关键代码,出现学号)

运行结果:

可以看出会产生乱码,这是因为FileReader继承自InputStreamReader,并利用它完成字节流到字符流的转换,而且在转换时采取的字符集为系统的默认字符集,即GBK。于是在UTF-8 -> GBK -> UTF-8的过程中编码出现损失,导致其出现了乱码。解决方法如下:


3.2 编写方法convertGBK2UTF8(String src, String dst),可以将以GBK编码的源文件src转换成以UTF8编码的目的文件dst。
方法如下:

4. 字节流、二进制文件:DataInputStream, DataOutputStream、ObjectInputStream
4.1 参考DataStream目录相关代码,尝试将三个学生对象的数据写入文件,然后从文件读出并显示。(截图关键代码,出现学号)





4.2 这里生成的文件和题目1生成的文件有何不一样?生成的文件有多大?分析该文件大小?将该文件大小和题目1生成的文件对比是大了还是小了,为什么?存储数据的时候,到底是二进制文件比较节省空间还是文本文件比较节省空间?使用二进制存储文件有何好处?
这里生成的文件是以.data为后缀名的数据文件,在这具体是指一个二进制文件。

可以看到生成的文件为72个字节,其中一个int为4个字节,一个汉字为3个字节,表明字符串所占的字节数为2个字节,一个double为8个字节,因此一行的字节数为4+3+3+4+8+2=24,三行的字节数为24*3=72.
和题目一的文件相比变大了,有上面的分析可以看出,存储一个int,double和中文字符所需的字节数都变多了,因此文件比第一题的大。
虽然从上面的分析来看似乎是文本文件更能节省空间,但是这个还是要看具体情况,当存储的数值很小的时候,文本文件所占用的空间可能会更小,但是如果要存储大量的数据,还是二进制文件更能节省空间。
使用二进制存储文件的好处如下:
- 二进制文件更能节省存储空间
- 对于某些比较精确的数据,二进制不会造成有效位数的丢失
- 计算机中使用的语言是二进制语言,因此用二进制存储就可以省去语言的转换过程
4.3 使用wxMEdit的16进制模式(或者其他文本编辑器的16进制模式)打开student.data,分析数据在文件中是如何存储的。

有点懒,就分析一行,其余两行类似:
00 00 00 01代表1
00 06 代表字符所占用的字节数,一个中文字符占三个字节
E5 BC A0 E4 B8 89代表张三
00 00 00 13 代表’19’
40 50 40 00 00 00 00 00 代表19.65
4.4 使用ObjectInputStream(读), ObjectOutputStream(写)读写学生。(截图关键代码,出现学号) //参考ObjectStreamTest目录



5. Scanner基本概念组装对象
编写public static List<Student> readStudents(String fileName)从fileName指定的文本文件中读取所有学生,并将其放入到一个List中。应该使用那些IO相关的类?说说你的选择理由。


答:要使用到的类有File类,FileInputStream类,InputStreamReader类,BufferedReader类,其中BufferedReader类中带有的较大的缓冲区可以让我们更快的进行数据的读写。
6. 选做:RandomAccessFile
6.1 使用RandomAccessFile实现题目1.1。(截图关键代码,出现学号)




6.2 分析文件大小

大小为72个字节,和4.2中的分析一样。
6.3 编写一个函数public Student getStuByIndext(int index),可以根据序号index使用RandomAccessFile从文件中将该学生的信息取出。(截图关键代码,出现学号)。并回答,哪里体现了RandomAccessFile对文件的随机访问特性。



RandomAccessFile可以通过seek(),skipBytes()以及length等方法定位到文件的任何一个位置,在此基位置上进行一些文件的操作。
7. 文件操作
编写一个程序,可以根据指定目录和文件名,搜索该目录及子目录下的所有文件,如果没有找到指定文件名,则显示无匹配,否则将所有找到的文件名与文件夹名显示出来。
7.1 编写public static void findFile(String path,String filename)函数,以path指定的路径为根目录,使用递归方式,在其目录与子目录下查找所有和filename相同的文件名,一旦找到就马上输出到控制台。(截图关键代码,出现学号)



7.2 使用队列、使用图形界面、使用Java NIO.2完成(任选1)



NIO.2的File工具类提供了一个walkFileTree来进行遍历,相比于上一题的递归,更加高效且优雅,然后在内部使用了遍历行为控制器FileVisitor,它是一个接口,里面提供四个方法来指定遍历过程中的事件处理,但是实际上,我在遍历时用的是直接继承FileVisitor的适配器SimpleFileVisitor,它相较于FileVisitor的好处就是可以不用实现四个方法,只需实现需要的方法即可。但是发现使用NIO.2遍历的文件似乎不会区分大小写耶。
7.3 选做:性能测试,测试你的findFile查找匹配文件的速度。有什么解决方案,可以让查找速度更快一些。比如类似Everything的搜索速度。
测试findFile的运行速度:

使用普通遍历法的运行时间:

使用NIO.2方法的遍历时间:

通过上面图片可以看出,使用NIO.2的运行时间更短,其实上题就说过了,使用NIO.2可以提高遍历的效率。
7.4 选做:实现删掉指定目录(如果该目录非空,删除掉该目录下及其子目录下的所有文件与目录)。

7.5 选做:将指定目录及子目录下的所有.java文件,转化成UTF-8编码格式,并测试。




8. 正则表达式
8.1 使用正则表达式判断给定的字符串是否是10进制数字格式?尝试编程进行验证,要给测试数据集及运行结果(可以转化为PTA)。(截图关键代码,出现学号)


8.2 解释自己编写的正则表达式。
我编写的正则表达式为^[-\\+]?[\\d]+[\\.]?[\\d]+$
^代表匹配输入字符串的开始位置
[-\\+]?代表字符串中”-”和”+”可以出现0次或1次
[\\d]+代表数字可以出现1次或多次
[\\.]?代表”.”可以出现0次或1次
$代表匹配输入字符串的结束位置
201621123031 《Java程序设计》第12周学习总结的更多相关文章
- 2018面向对象程序设计(Java)第12周学习指导及要求
2018面向对象程序设计(Java)第12周学习指导及要求 (2018.11.15-2018.11.18) 学习目标 (1) 掌握Java GUI中框架创建及属性设置中常用类的API: (2) 掌 ...
- 面向对象程序设计(JAVA) 第12周学习指导及要求
2019面向对象程序设计(Java)第12周学习指导及要求 (2019.11.15-2019.11.18) 学习目标 (1) 掌握Vetor.Stack.Hashtable三个类的用途及常用API ...
- 20145213《Java程序设计》第二周学习总结
20145213<Java程序设计>第二周学习总结 教材学习内容总结 本周娄老师给的任务是学习教材的第三章--基础语法.其实我觉得还蛮轻松的,因为在翻开厚重的书本,一股熟悉的气息扑面而来, ...
- 21045308刘昊阳 《Java程序设计》第九周学习总结
21045308刘昊阳 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 数据库本身是个独立运行的应用程序 撰 ...
- 20175209 《Java程序设计》第九周学习总结
20175209 <Java程序设计>第九周学习总结 一.教材知识点总结 有关数据库下载中存在可能出现的问题已经在博客<数据库安装和使用过程中出现的一些问题>给出了相应的解决办 ...
- 20175221 2018-2019-2 《Java程序设计》第一周学习总结
20175221 2018-2019-2 <Java程序设计>第一周学习总结 教材学习内容总结 本周通过观看书本配套视频,学到了如解释器,编译器等一些简单概念. 还懂得了java的一些简单 ...
- 20175204 张湲祯 2018-2019-2《Java程序设计》 第一周学习总结
20175204 张湲祯 2018-2019-2<Java程序设计>第一周学习总结 教材学习内容总结 -第一章Java入门要点: -Java的地位:具有面向对象,与平台无关,安全稳定和多线 ...
- 20175227张雪莹 2018-2019-2 《Java程序设计》第九周学习总结
20175227张雪莹 2018-2019-2 <Java程序设计>第九周学习总结 教材学习内容总结 第十一章 JDBC数据库操作 MySQL数据库管理系统 下载安装MySQL 若下载的是 ...
- 20175314 《Java程序设计》第九周学习总结
20175314 <Java程序设计>第九周学习总结 教材学习内容总结 根据课本的介绍下载了MySQL和Navicat for MySQL并成功对后者进行破解 MySQL客户端管理工具(如 ...
- 20175234 2018-2019-2 《Java程序设计》第九周学习总结
目录 20175234 2018-2019-2 <Java程序设计>第九周学习总结 教材学习内容总结 教材学习中的问题和解决过程 代码托管 感想 学习进度条 参考资料 20175234 2 ...
随机推荐
- javax顶层接口分析
1.Servlet接口分析 此接口是Servlet的最顶层接口,其中定义了Servlet生命周期相关的方法,所有Servlet都必须实现.此接口中的方法有以下几个: public void init( ...
- RobotFramework下的http接口自动化Get关键字的使用
在使用Create Http Context关键字创建了http的调用环境后,就可以使用Get关键字来发送一个http协议中最常用的get请求了. Get 关键字只接受一个url参数,该关键字的API ...
- 第三篇:数据可视化 - ggplot2
前言 R语言的强大之处在于统计和作图.其中统计部分的内容很多很强大,因此会在以后的实例中逐步介绍:而作图部分的套路相对来说是比较固定的,现在可以先对它做一个总体的认识. 在上一篇文章中,介绍了使用gr ...
- c#抽取pdf文档标题(4)——机器学习以及决策树
我的一位同事告诉我,pdf抽取标题,用机器学习可以完美解决问题,抽取的准确率比较高.于是,我看了一些资料,就动起手来,实践了下. 我主要是根据以往历史块的特征生成一个决策树,然后利用这棵决策树,去判断 ...
- 关于Android attrs 自定义属性的说明
写个自定义控件时经常要自定义一些自己的属性,平时用的都是那几个,今天就顺便一起总结一下这个东东吧- 一.定义:属性的定义都在attrs.xml文件里面: 二.读取:通过都是通过TypedArray去读 ...
- JavaScript之事件及动画
一.事件 常用事件 click(function(){...}) //单击事件 hover(function(){...}) //鼠标经过事件 blur(function(){...}) //失去光标 ...
- java抽象类注意问题
当知道一个类的子类将不同的实现某个方法时,把该类声明为抽象类很有用,可以共用相同的父类方法,不必再定义. 抽象类和抽象方法的关系:含有抽象方法的类一定是抽象类,抽象类里不一定含有抽象方法. 抽象类存在 ...
- lamp进阶
前言:上一文说到,在lamp上简单的部署应用程序,wordpress和phpmyadmin 稍稍回顾一下,动态页面apche发往后端类PHP程序,其PHP本身提供能与后端mysql进行交互的驱动,使得 ...
- Linux环境下jdk1.8压缩包下载
jdk1.8下载: 百度云链接:https://pan.baidu.com/s/1c37VcPi 密码:e6qh
- mysql主从复制的基本原理
怎么安装mysql数据库,这里不说了,只说它的主从复制,步骤如下: 1.主从服务器分别作以下操作: 1.1.版本一致 1.2.初始化表,并在后台启动mysql 1.3.修改root的密码 2.修 ...