我正在教自己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;
}
}
答案 0 :(得分:2)
您永远不会关闭您的BufferedWriter。因此,您的输出将被缓冲,并且永远不会刷新到基础文件。
由于您正在尝试Java 7新API,因此您应该使用新的try-with-resources,它会自动关闭编写器并避免此类错误。 (顺便说一下,你用它来阅读,但不要写。总是使用它,或者总是在最后一个块中关闭流,读者和作者)