zoukankan      html  css  js  c++  java
  • 20145107 《Java程序设计》第八周学习总结

    20145107 《Java程序设计》第八周学习总结

    教材学习内容总结

    在本周,我们进行了教材第十四,十五章的学习,本周的学习目标是:
    了解NIO
    会使用Channel、Buffer与NIO2
    会使用日志API、国际化
    会使用正则表达式
    了解JDK8增强功能

    第十四章:

    NIO2文件系统:

    • 1.有关NIO2文件的操作路径:
      想要操作文档,就要先指出文档的路径。path实例是在JVM中的路径的代表对象。也是NIO2文件系统API的操作起点,NIO2文件系统API中有许多操作,都必须使用path指定路径。path实际只代表路径信息,也就是说,该路径所对应的文档或文件夹不一定存在,在java中,path提供一种方法去的路径的各种信息。就像下面的程序:
    package cc.openhome;
    
    import java.nio.file.*;
    import static java.lang.System.out;
    
    public class PathDemo {
        public static void main(String[] args) {
            Path path = Paths.get(
                    System.getProperty("user.home"), "Documents", "Downloads");
            out.printf("toString: %s%n", path.toString());
            out.printf("getFileName: %s%n", path.getFileName());
            out.printf("getName(0): %s%n", path.getName(0));
            out.printf("getNameCount: %d%n", path.getNameCount());
            out.printf("subpath(0,2): %s%n", path.subpath(0, 2));
            out.printf("getParent: %s%n", path.getParent());
            out.printf("getRoot: %s%n", path.getRoot());
        }
    } 
    
    

    此程序在IDEA中的执行情况如下所示:

    • 2.文件的属性读取与设定:
      在以前,并没有标准方式取得不同文件系统所支持的不同属性,在JDK7中,可以通过BasicFileAttributes,DosFileAttributes,PosixFileAttributes,可以针对不同的文件系统取得支持的属性信息。
      BasicFileAttributes就是取得各文件系统中都支持的属性,可以通过File.readAttributes()取得BasicFileAttributes实例,对应的代码如下:
    package cc.openhome;
    
    import java.io.IOException;
    import static java.lang.System.out;
    import java.nio.file.*;
    import java.nio.file.attribute.BasicFileAttributes;
    
    public class BasicFileAttributesDemo {
        public static void main(String[] args) throws IOException {
            Path file = Paths.get("C:\Windows");
            BasicFileAttributes attrs = 
                    Files.readAttributes(file, BasicFileAttributes.class);
            out.printf("creationTime: %s%n", attrs.creationTime());
            out.printf("lastAccessTime: %s%n",  attrs.lastAccessTime());
            out.printf("lastModifiedTime: %s%n", attrs.lastModifiedTime());
            out.printf("isDirectory: %b%n", attrs.isDirectory());
            out.printf("isOther: %b%n", attrs.isOther());
            out.printf("isRegularFile: %b%n",  attrs.isRegularFile());
            out.printf("isSymbolicLink: %b%n", attrs.isSymbolicLink());
            out.printf("size: %d%n", attrs.size());
        }
    } 
    
    

    相应执行的结果如下:

    如果想取得储存装置本身的信息,可以利用Files.getFileStore()方法取得所有存储装置的FileStore实例。下面这个程序可以利用FileStore计算磁盘的使用率:

    package cc.openhome;
    
    import java.io.IOException;
    import static java.lang.System.out;
    import java.nio.file.*;
    import java.text.DecimalFormat;
    
    public class Disk {
        public static void main(String[] args) throws IOException {
            if (args.length == 0) {
                FileSystem fs = FileSystems.getDefault();
                for (FileStore store: fs.getFileStores()) {
                    print(store);
                }
            } 
            else {
                for (String file: args) {
                    FileStore store = Files.getFileStore(Paths.get(file));
                    print(store);
                }
            }
        }
        
        public static void print(FileStore store) throws IOException {
            long total = store.getTotalSpace();
            long used = store.getTotalSpace() - store.getUnallocatedSpace();
            long usable = store.getUsableSpace();
            DecimalFormat formatter = new DecimalFormat("#,###,###");
            out.println(store.toString());
            out.printf("	- 总容量	%s	位元组%n", formatter.format(total));
            out.printf("	- 可用空间	%s	位元组%n", formatter.format(used));
            out.printf("	- 已用空间	%s	位元组%n", formatter.format(usable));
        }
    }
    
    

    程序执行后,我的电脑中磁盘的相关信息就显示了出来:

    • 3.操作文档与目录:
      如果想要删除path代表的文档或目录,可以使用Files.delete()方法,但这个方法会出现一系列的问题。我们可以使用更高级的办法Files.deleteIfExists()方法删除文档。如果想要复制来源path的文档或目录至目的地path,可以使用File.copy()方法,这个方法的第三个选项会指定CopyOption接口的操作对象。File.copy还有两个重载的版本,一个是接受InputStream作为来源,可以直接读取数据,并将结果复制到指定的Path中;另一个File.copy()版本是将来源Path复制到指定的OutputStream,书中有一个相应的程序:
    package cc.openhome;
    
    import java.io.*;
    import java.net.URL;
    import java.nio.file.*;
    import static java.nio.file.StandardCopyOption.*;
    
    public class Download {
        public static void main(String[] args) throws IOException {
            URL url = new URL(args[0]);
            Files.copy(url.openStream(), Paths.get(args[1]), REPLACE_EXISTING);
        }
    }
    
    

    若要进行文档或目录移动,可以使用File.move方法,使用方式与File.copy方法类似,可以指定来源Path,目的地Path与CopyOption。如果要建立目录则可以使用Files.createDirectory()方法。

    • 4.读取访问目录:
      如果想取得文件系统根目录的信息,可以使用FileSystem的getRootDirectories方法相应的程序如下:
    package NIO2;
    
    
    
            import static java.lang.System.out;
            import java.nio.file.*;
    
    public class Roots {
        public static void main(String[] args) {
            Iterable<Path> dirs = FileSystems.getDefault().getRootDirectories();
            dirs.forEach(out::println);
        }
    }
    
    

    相应的程序执行如下:

    也可以使用File.newDirectoryStream()方法取得DirectoryStream接口操作对象,代表指定路径下的所有文档。下面这个程序可以从命令行自变量指定目录路径,查询出该目录下的文档:

    package NIO2;
    
    
    
            import java.io.IOException;
            import static java.lang.System.out;
            import java.nio.file.*;
            import java.util.*;
    
    public class Dir {
        public static void main(String[] args) throws IOException {
            try(DirectoryStream<Path> directoryStream =
                        Files.newDirectoryStream(Paths.get(args[0]))) {
                List<String> files = new ArrayList<>();
                for(Path path : directoryStream) {
                    if(Files.isDirectory(path)) {
                        out.printf("[%s]%n", path.getFileName());
                    }
                    else {
                        files.add(path.getFileName().toString());
                    }
                }
                files.forEach(out::println);
            }
        }
    }
    
    

    第十五章:

    日志:

    • 1.java.util.logging包提供了日志功能相关的类与接口,其好处是不用加入额外配置的日志组件就可以在标准的java平台上使用。日志的起点是logger类。在调用getLogger类时必须制定Logger实例所指定的名称空间,名称空间以“.”作为层级区分,层级相同的Logger其父Logger组态相同。在取得Logger实例后,可以用log方法输出信息例如:
    package Logging;
    
    
    
            import java.util.logging.*;
    
    public class LoggerDemo {
        public static void main(String[] args) {
            Logger logger = Logger.getLogger(LoggerDemo.class.getName());
            logger.log(Level.WARNING, "WARNING 讯息");
            logger.log(Level.INFO, "INFO 讯息");
            logger.log(Level.CONFIG, "CONFIG 讯息");
            logger.log(Level.FINE, "FINE 讯息");
        }
    }
    
    

    相应的程序执行情况如下:

    -2.使用Handler与Formatter:

    在java中负责日志输出的是Handler实例,Logger可以使用addHandler()新增handler实例,使用RomoveHandler移除实例,书中有一个程序范例,可以将目前Logger与新建的FileHandler层级设定Level.CONFIG,并使用addHandler()设定至Logger实例:

    package Logging;
    
    
    
            import java.io.IOException;
            import java.util.logging.*;
    
    public class HandlerDemo {
        public static void main(String[] args) throws IOException {
            Logger logger = Logger.getLogger(HandlerDemo.class.getName());
            logger.setLevel(Level.CONFIG);
            FileHandler handler = new FileHandler("%h/config.log");
            handler.setLevel(Level.CONFIG);
            logger.addHandler(handler);
            logger.config("Logger 组装完成");
        }
    }
    
    
    • 3.自定义Handler,Formatter与Filter:

      如果java.util.logger包中提供的Handler成果都不符合要求,可以继承Handler类,操作抽象方法publish(),flush(),close()方法来自定义Handler,建议操作时考虑信息过滤与格式化。如果要自定义Fomatter,可以继承Fomatter后操作抽象方法format(),这个方法会传入LogRecord,储存所有的日志信息。下面的程序将ConsoleHandler的Formatter设定为自定义的Formatter:

    package Logging;
    
    
    
            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() + "
    "
                            + "	层级	: " + record.getLevel() + "
    "
                            + "	讯息	: " + record.getMessage() + "
    "
                            + "	时间	: "  + Instant.ofEpochMilli(record.getMillis())
                            + "
    ";
                }
            });
            logger.addHandler(handler);
            logger.config("自订 Formatter 讯息");
        }
    }
    
    

    程序相应的执行范例如下:

    规则表示式:

    • 1.规则表示式简介:
      如果我想根据某个字符串或字符进行切割,可以使用String的split()方法,它会返回切割后各子字符串组成的String数组。就像下面的程序:
    import static java.lang.System.out;
    
    public class SplitDemo {
        public static void main(String[] args) {
            // 根据逗号切割
            for(String token : "Justin,Monica,Irene".split(",")) {
                out.println(token);
            }
            // 根据Orz切割
            for(String token : "JustinOrzMonicaOrzIrene".split("Orz")) {
                out.println(token);
            }
            // 根据Tab字元切割
            for(String token : "Justin	Monica	Irene".split("\t")) {
                out.println(token);
            }
        }
    } 
    
    

    相应的程序执行范例如下:

    • 2.边界比较

      在java的编程中,我们可以使用来标出单词边界,就像下面这个程序:

    package Regex;
    
    
    
    public class SplitDemo3 {
        public static void main(String[] args) {
            for(String str : "Justin dog Monica doggie Irene".split("\bdog\b")) {
                System.out.println(str.trim());
            }
        }
    }
    
    

    相应的程序代码如下:

    • 3.JDK8API增强功能:

      1.如果我们有一组字符串,我们想要指定每个字符串之间以“,”进行分隔,现在,我们可以使用String新增的join()静态方法。
      2.对于数组操作,在JDK8中针对大型数组的平行化操作,在Arrays上新增了parallelPrefix(),ParallelSetall()与parallelSort()方法。

    本周代码托管截图

    本周代码数量截图:

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 200/200 2/2 20/20
    第二周 100/300 1/3 18/38
    第三周 200/500 1/4 22/60
    第四周 250/750 1/5 30/90
    第五周 450/1200 1/6 20/110
    第六周 400/1600 2/8 30/140
    第七周 150/1750 2/10 30/170
    第八周 500/2250 2/12 30/200

    参考资料

  • 相关阅读:
    centos7 安装mysql
    基于flask+requests 个人博客
    python csv、json、pickle数据持久化
    Python之容器、迭代器、生成器
    AJAX常用方法详解
    Python之format详解
    Flask使用MySql数据库
    git 公共服务器
    pci 记录
    检查ept
  • 原文地址:https://www.cnblogs.com/20145107lcd/p/5424642.html
Copyright © 2011-2022 走看看