20155208徐子涵 2016-2017-2 《Java程序设计》第8周学习总结
教材学习内容总结
第14章 NIO与NIO2
14.1 认识NIO
-
NIO概述 NIO使用频道(Channel)来衔接数据节点,在处理数据时,NIO可以设定缓冲区(Buffer)容量,在缓冲区中对感兴趣的数据区块进行标记,像是标记读取位置、数据有效位置,对于这些区块标记,提供了clear()、rewind()、flip()、compact()等高级操作。
-
下面用NIO的方法来实现10.1.1中的dump()方法,代码如下:
public static void dump(ReadableByteChannel src,WritableByteChannel dest)throws IOException{
ByteBuffer buffer = ByteBuffer.allocate(1024);
try(ReadableByteChannel srcCH = src;WritableByteChannel destCH = dest){
while(srcCH.read(buffer)!=-1){
buffer.flip();
destCH.write(buffer);
buffer.clear();
}
}
}
14.2 NIO2文件系统
-
NIO2文件系统API提供一组标准接口与类,应用程序开发者只要基于这些标准接口与类进行文件系统操作,底层实际如何进行文件系统操作,是由文件系统提供者负责(由厂商操作)。
-
应用程式开发者可以通过java.nio.file套件中FileSystems、Paths、Files等类提供的静态方法,取得相关操作对象或进行各种文件系统操作,这些静态方法内部会运用FileSystemProvider来取得所需的操作对象,完成应有的操作。
第十五章 通用API
15.1 日志
java.util.logging
包提供了日志功能相关类与接口,不必额外配置日志组件,就可在标准Java平台使用是其好处。使用日志的起点是Logger类,要取得Logger
实例,必须使用Logger
的静态方法getLogger()
。如:
Logger logger = Logger.getLogger("cc.openhome.Main"); 调用getLogger()
时,必须指定Logger
实例所属名称空间,名称空间以“.”作为层级区分,名称空间层级相同的Logger
,其父Logger
组态相同。
Logger
是记录信息的起点,要输出的信息,必须先通过Logger
的Level
与Filter
过滤,再通过Handler
的Level
与Filter
过滤,格式化信息的动作交给Formatter
,输出信息的动作实际上是Handler
负责。
负责日志输出的是Handler
实例,Handler
的子类有MemoryHandler
和StreamHandler
,StreamHandler
的子类有ConsoleHandler、FileHandler和SocketHandler
。
Formatter的子类有XMLFormatter和SimpleFormatter,FileHandler默认的Formatter是XMLFormatter,ConsoleHandler默认则使用SimpleFormatter。
如果要自定义Handler,可以继承Handler类,操作抽象方法publish()、flush()、close()。
如果要自定义Formatter,可以继承Formatter后操作抽象方法formatter(),这个方法会传入LogRecord,储存所有日志信息。例如,将ConsoleHandler的Formatter设定为自定义的Formatter:
import java.time.Instant;
import java.util.logging.*;
public class FormatterDemo {
public static void main(String[] args) {
Logger logger = Logger.getLogger(FormatterDemo.class.getName());
logger.setLevel(Level.CONFIG);
ConsoleHandler handler = new ConsoleHandler();
handler.setLevel(Level.CONFIG);
handler.setFormatter(new Formatter() {
@Override
public String format(LogRecord record) {
return "日志来自 " + record.getSourceClassName() + "."
+ record.getSourceMethodName() + "\n"
+ "\t层级\t: " + record.getLevel() + "\n"
+ "\t信息\t: " + record.getMessage() + "\n"
+ "\t时间\t: " + Instant.ofEpochMilli(record.getMillis())
+ "\n";
}
});
logger.addHandler(handler);
logger.config("自定义 Formatter 信息");
}
}
可以通过logging.properties来设定Logger组态,启动JVM时,指定java.util.logging.config.file系统属性为.properties名称。
15.2 国际化基础
- 对于日后可能变动的文字信息,可以考虑将信息移至程序之外,方法是使用ResourceBundle来做信息绑定。首先要准备一个.properties文档,如messages.properties,而文档内容如下:
cc.openhome.welcome=Hello
cc.openhome.name=World
.properties文档必须放置在CLASSPATH的路径设定下,文档中撰写的是键/值配对,之后在程序中可以使用键来取得对应的值。例如:
import static java.lang.System.out;
import java.util.ResourceBundle;
public class Hello {
public static void main(String[] args) {
ResourceBundle res = ResourceBundle.getBundle("messages");
out.print(res.getString("cc.openhome.welcome") + "!");
out.println(res.getString("cc.openhome.name") + "!");
}
}
-
国际化的三个重要概念是地区信息、资源包与基础名称。地区信息的对应类是Locale,ResourceBundle对象是JVM中资源包的代表对象。代表同一组信息但不同地区的各个资源包会共享相同的基础名称,使用ResourceBundle的getBundle()时指定的名称,就是在指定基础名称。
-
地区信息代表了特定的地理、政治或文化区,地区信息可由一个语言编码与可选的地区编码来指定。其中语言编码由两个小写字母代表,如zh表示中文;地区编码则由两个大写字母表示,如TW表示我国台湾。
-
使用ResourceBundle时,如何根据基础名称取得对应的信息文档:
(1)使用指定的Locale对象取得信息文档。 (2)使用Locale.getDefault()取得的对象取得信息文档。 (3)使用基础名称取得信息文档。
15.3 规则表达式
规则表示式基本上包括两种字符:字面意义字符与元字符。字面意义字符是指按照字面意义比较的字符;元字符是不按照字面比较,在不同情境有不同意义的字符。
规则表示式主要用于字符、字符串格式比较,java.util.regex.Pattern实例是规则表示式在JVM中的代表对象,必须通过Pattern的静态方法compile()来取得,可以使用matcher()方法指定要比较的字符串,这会返回java.util.regex.Matcher实例,表示对指定字符串的比较器。
教材学习中的问题和解决过程
问题: 针对P481 Hello.java提出的问题(如下)有疑惑:
messages.properties放什么位置?
研究ResourceBundle类。
解决过程:
通过学习教材,得到如下解释:
properties文档必须放置在CLASSPATH的路径设定下。
ResourceBundle的静态getBundle()方法会取得一个ResourceBundle的实例,所给定的自变量名称是信息文档的主文件名,getBundle()会自动找到对应的.properties文档,取得ResourceBundle实例后,可以使用getString()指定键来取得文档中对应的值,如果日后想要改变现实的信息,只要改变.properties文档的内容就可以了。
代码调试中的问题和解决过程
本周无问题
代码托管截图
其他(感悟、思考等,可选)
这周的学习目标主要是第十五章,需要我们学会使用日志API、了解国际化基础、认识JDK8增强功能等。通过前面几周的学习,java的核心知识与难点之前都已经学完了,后面的章节大概都是介绍一些类的应用。在以后的学习中,将会把重点放在实验博客的撰写上面,感觉实验才是检验学习的真正方法和途径,希望自己能够认真的完成老师布置的每次实验。
上周错题总结
-
错题1: 哪些Linux 命令可以ASCII码和16进制单字节方法输出Hello.java的内容?
od -tcx1 Hello.java和od -tc -tx1 Hello.java
-
错题2: JDK8中的(Stream API),可以用来实现管道操作
-
错题3 JDK8 中新时间API中,用于度量时间的类有() A .Instant B .Duration C .Period D .LocalDateTime
答案:BC
点评过的同学博客和代码
学习进度条
代码行数(新增/积累) | 博客量(新增/积累 | 学习时间(新增/累积) | |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
第一周 | 16/16 | 1/1 | 8/8 |
第二周 | 120/120 | 2/2 | 12/12 |
第三周 | 130/150 | 1/1 | 9/9 |
第四周 | 180/200 | 1/1 | 15/15 |
第五周 | 150/300 | 1/1 | 12/12 |
第六周 | 120/300 | 1/1 | 8/8 |
第七周 | 300/300 | 2/2 | 10/10 |
第八周 | 100/300 | 1/1 | 7/7 |