0

我正在自学 NIO2 并做一些实践来测试理论。目前我已经实现了 FileVisitor,它可以编译和运行,并在 fileVisit 中执行我期望的操作,但在 postFileVisit 中没有。也就是说,它会计算 .xml 和 .xhtml 文件中的表格行数,并使用结果创建一个文本文件,但它不会附加给定目录的表格行总数。然而,postFileVisit 确实做了一些事情,如果一个目录没有 .xml 或 .xhtml 文件,仍然会创建一个日志文件并加盖时间戳,但代码行 97 到 101 似乎没有效果。所以,我相信这是我搞砸的 BufferedWriter 的问题。谢谢您的帮助:

    package com.purposeful_play.BasicIO;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.nio.file.*;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileTime;

/**
 *
 * @author Michael-Mosher
 */

public class CharacterCounter<T> implements FileVisitor<T> {
    static int count = 0;

    public static void main (String[] args){
        Path path = FileSystems.getDefault().getPath(args[0]);

        try { 
Files.walkFileTree(path, new CharacterCounter<Path>());
        }
        catch (IOException x) { System.err.format("Unable to read file: %s%n", x); }

    }

    @Override
    public FileVisitResult preVisitDirectory(Object dir, BasicFileAttributes attrs) throws IOException {
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Object file, BasicFileAttributes attrs) throws IOException {
       Path fname = (Path)file;
        if((fname.getFileName().toString().contains(".xhtml"))||(fname.getFileName().toString().contains(".xml"))){
        boolean withindiv = false;
        int fcount = 0;
        StringBuilder div = new StringBuilder("<div ID=center");
        StringBuilder notdiv = new StringBuilder("</div");
        StringBuilder table = new StringBuilder("<tr");
        Charset cs = Charset.forName("UTF-8");
        try (BufferedReader input = Files.newBufferedReader((Path)file, cs)){
        while(input.ready()){
            String line = input.readLine();
            withindiv = line.contains(div) ? line.contains(div) : withindiv;
            if(withindiv){
                withindiv = !(line.contains(notdiv));
                if(!withindiv){
                    line = line.split("</div")[0];
                }
                fcount = line.split("<tr", 0).length-1;
                count += fcount;
            }
        }

            }
        Path path = (Path)file;
        String ss = path.toString();
        path = path.getParent().resolve("logfile.txt");
        boolean newfile = Files.exists(path);
        try (BufferedWriter output = Files.newBufferedWriter(
                path, cs, StandardOpenOption.CREATE, 
                StandardOpenOption.APPEND)){
        output.write(ss);
        output.newLine();
        ss = new Integer(fcount).toString();
        output.write(ss);
        output.newLine();
        long currentTime = System.currentTimeMillis();
        FileTime ft = FileTime.fromMillis(currentTime);
        if(!newfile)
            Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(ft, null, ft);
        else 
            Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(ft, null, null);
        }
    } // End if(...xhtml || ...xml)
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Object file, IOException exc) throws IOException {
        System.err.printf("visitFileFailed error: %s%n", exc);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Object dir, IOException exc) throws IOException {
        Path path = (Path)dir;
        path = path.resolve("logfile.txt");
        Charset cs = Charset.forName("UTF-8");
        BufferedWriter output = Files.newBufferedWriter(path, cs, 
                StandardOpenOption.CREATE, StandardOpenOption.SYNC, StandardOpenOption.WRITE, StandardOpenOption.APPEND);
        String ss = "Total occurences: ";
        output.write(ss);
        output.newLine();
        ss = new Integer(count).toString();
        output.write(ss);
        output.newLine();
        count = 0;
        long time = System.currentTimeMillis();
        FileTime ft = FileTime.fromMillis(time);
        Files.setLastModifiedTime(path, ft);
        return FileVisitResult.CONTINUE;
    }
    }
4

1 回答 1

2

你永远不会关闭你的 BufferedWriter。所以你的输出是缓冲的,永远不会刷新到底层文件。

由于您正在试验 Java 7 的新 API,您应该使用新的try-with-resources,它会自动关闭编写器并避免此类错误。(顺便说一句,您使用它来读取,但不用于写入。始终使用它,或始终在 finally 块中关闭流、读取器和写入器)

于 2012-04-30T17:14:54.400 回答