2012-04-30 59 views
1

我在教自己NIO2並做一些實踐實現來測試理論。目前,我已經完成了一個FileVisitor的實現,它編譯並運行,並執行我期望的fileVisit,但不是在postFileVisit中。也就是說,它計算.xml和.xhtml文件中的表格行,並創建一個包含結果的文本文件,但不會附加給定目錄的表格行總數。但是,postFileVisit確實可以做一些事情,因爲如果一個目錄沒有.xml或.xhtml文件,那麼仍然會創建一個日誌文件並添加時間戳,但代碼行97到101似乎沒有影響。所以,我相信這是BufferedWriter的東西,我搞砸了。謝謝你的幫助:NIO2 n00b,FileVisitor/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; 
    } 
    } 

回答

2

你永遠不會關閉你的BufferedWriter。所以你的輸出被緩衝,並且永遠不會刷新到底層文件。

由於您正在試驗Java 7新的API,因此您應該使用新的try-with-resources,它會自動關閉寫入程序並避免此類錯誤。 (順便說一下,你用它來閱讀,但不寫,始終使用它,或總是關閉流,讀者和作家在一個finally塊)

+0

謝謝,@JB Nizet。 –