0

私は独学で NIO2 を学んでおり、理論をテストするためにいくつかの実践的な実装を行っています。現在、コンパイルして実行し、fileVisit で期待することを実行する FileVisitor の実装を作成しましたが、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 を使用する必要があります。これにより、ライターが自動的に閉じられ、そのようなバグが回避されます。(ちなみに、読み取りには使用しますが、書き込みには使用しません。常に使用するか、最終ブロックで常にストリーム、リーダー、ライターを閉じてください)

于 2012-04-30T17:14:54.400 に答える