NIO2 n00b,FileVisitor / BufferedWriter

时间:2012-04-30 17:09:05

标签: java nio2

我正在教自己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;
    }
    }

1 个答案:

答案 0 :(得分:2)

您永远不会关闭您的BufferedWriter。因此,您的输出将被缓冲,并且永远不会刷新到基础文件。

由于您正在尝试Java 7新API,因此您应该使用新的try-with-resources,它会自动关闭编写器并避免此类错误。 (顺便说一下,你用它来阅读,但不要写。总是使用它,或者总是在最后一个块中关闭流,读者和作者)