当前位置: 首页 > 面试题库 >

为什么Java 7 Files.walkFileTree在远程驱动器上遇到tar文件时引发异常

濮阳景天
2023-03-14
问题内容

我曾使用Files.WalkFileTree()过导航文件夹和计数音频文件的功能,但是遇到tar文件时会出现问题,似乎将其视为实际的文件夹,我希望它会跳过它。

我看不到任何可以控制这种行为的选项

码:

package com.jthink.songkong.fileloader;


import com.jthink.songkong.cmdline.SongKong;
import com.jthink.songkong.ui.MainWindow;

import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.Callable;
import java.util.logging.Level;

/**
 * Count the number of files that can be loaded, for information purposes only
 */
public class CountFilesinFolder implements Callable<Boolean> {
    public static class CountFiles
            extends SimpleFileVisitor<Path> {
        private int fileCount = 0;
        private final PathMatcher matcher;

        CountFiles(String pattern) {
            matcher =
                    FileSystems.getDefault()
                            .getPathMatcher("regex:" + pattern);
        }

        /**
         * Find Music file
         *
         * @param file
         * @param attr
         * @return
         */
        @Override
        public FileVisitResult visitFile(Path file,
                                         BasicFileAttributes attr) {
            Path name = file.getFileName();
            if (name != null && matcher.matches(name)) {
                fileCount++;
            }
            return FileVisitResult.CONTINUE;
        }

        public int getFileCount() {
            return fileCount;
        }
    }


    private Path scanDir;
    public CountFilesinFolder(Path scanDir) {
        this.scanDir = scanDir;
    }

    public Boolean call() {
        CountFiles countFiles = null;
        try {
            countFiles = new CountFiles("^(?!._).*[.](?:mp3|mp4|m4p|m4b|m4a|ogg|flac|wma)$");
            Files.walkFileTree(scanDir, countFiles);
        }
        catch (Exception e) {
            MainWindow.logger.log(Level.SEVERE, "Unable to find file for deriving base folder", e);
        }
        MainWindow.logger.severe("Music File Count:"+countFiles.getFileCount());
        SongKong.setMaxProgress(countFiles.getFileCount());
        return true;
    }
}

给出这个堆栈跟踪

java.nio.file.NoSuchFileException: Z:\Scratch\fred.tar
    at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
    at sun.nio.fs.WindowsDirectoryStream.<init>(WindowsDirectoryStream.java:86)
    at sun.nio.fs.WindowsFileSystemProvider.newDirectoryStream(WindowsFileSystemProvider.java:526)
    at java.nio.file.Files.newDirectoryStream(Files.java:411)
    at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:179)
    at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:199)
    at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:69)
    at java.nio.file.Files.walkFileTree(Files.java:2591)
    at java.nio.file.Files.walkFileTree(Files.java:2624)
    at com.jthink.songkong.fileloader.CountFilesinFolder.call(CountFilesinFolder.java:68)
    at com.jthink.songkong.fileloader.CountFilesinFolder.call(CountFilesinFolder.java:15)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

但这是一个远程驱动器(nas驱动器),我在本地驱动器上没有得到这样的错误

编辑 基于以下我认为可行的答案实施了以下内容

    @Override
            public FileVisitResult preVisitDirectory(Path dir, 
BasicFileAttributes attrs)
                    throws IOException {
                if(dir.endsWith(".tar"))
                {
                    return FileVisitResult.SKIP_SUBTREE;
                }
                return super.preVisitDirectory(dir, attrs);
            }

但是我的测试不对劲,它实际上不起作用,因为FileTreeWalker中失败的代码在previsit方法之前被调用

try {
            DirectoryStream<Path> stream = null;
            FileVisitResult result;

            // open the directory
            try {
                stream = Files.newDirectoryStream(file);
            } catch (IOException x) {
                return visitor.visitFileFailed(file, x);
            } catch (SecurityException x) {
                // ignore, as per spec
                return FileVisitResult.CONTINUE;
            }

            // the exception notified to the postVisitDirectory method
            IOException ioe = null;

            // invoke preVisitDirectory and then visit each entry
            try {
                result = visitor.preVisitDirectory(file, attrs);
                if (result != FileVisitResult.CONTINUE) {
                    return result;
                }

问题答案:

解决当前问题的方法:

但是实现一个visitFileFailed,您应该可以。

public class MyFileVisitor extends SimpleFileVisitor<Path> {
    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
        if (file.toString().endsWith(".tar")) {
            return FileVisitResult.CONTINUE;
        }
        return super.visitFileFailed(file, exc);
    }
}

更新:如果我们仔细观察,可以看到walkFileTree使用Files.readAttributes
,该文件转向正在使用的当前提供程序:WindowsFileSystemProvider.readAttributes来确定路径是否为目录。

正如评论中提到的那样,我也不认为错误在于Java实现,而是OS本地调用返回错误的属性

如果要解决此问题,一种选择是实现自己的文件系统,该文件系统透明地包装WindowsFileSystem实现,但readAttributes返回.tar-
paths作为文件而不是dir。



 类似资料:
  • 我的Spring启动应用程序, 在获得Whitelabel错误页面后,我在我的一个控制器中映射了, 我映射了一个,出现以下异常:, 遵循User9123的解决方案,但是,我仍然得到下面的页面,

  • 问题内容: 我在用于SQLite的JDBC驱动程序中有问题。 我正在用SELECT语句执行查询。 如果我得到一个空(0行),则在调用时会抛出“ Closed ResultSet”异常。 没有大量的JDBC经验,我的理论(我无法通过JavaDocs确认)是 对空(零行)结果集不起作用(通过设计或由于错误) 的“打开”标志设置为零行(同样是设计或错误) 我看到了此错误报告,但不确定是否相关。 我的要求

  • 我正在尝试使用Java中的Apache commons compress将tar文件解压缩为。我能够解压缩大部分的tar文件,但很少有失败的,除了下面的例外。我不确定是什么引起了这个问题。tar文件是否已损坏?我可以在windows中使用7zip解压缩文件,但相同的文件在编程解压缩时失败。我正在使用Appache commons-compress1.18 下面是我的代码

  • 我必须点击页面上的某个按钮。但是,当我检索所有具有特定类名的元素时。当我尝试执行每个元素或单击时,所有检索到的元素都会抛出一个过时的引用异常。我不能双击任何一个。它找到了正确的元素,但抛出了所有元素的例外。注释掉的代码就是我试图选择并点击相应按钮的地方。我附上了表格的照片。请注意,每次单击或执行按钮时,页面都会发生更改。选择上传BOM按钮是您需要特别注意的。网站

  • 我想上传一个文件到不同的服务器使用卷曲。我读过许多类似的问题,但我没有得到任何解决我的问题。下面是我现在得到的代码: 当我运行此脚本时,它将保持运行200秒,并以以下方式响应: Sep 17 20:56:58 xxxxx vsftpd[2613]:[user]确定登录:客户端“yyyyy” Sep 17 20:56:58 xxxxx vsftpd[2618]:[用户]FTP响应:客户端“YYYYY

  • 我在Mac OS Big Sur 11.4上使用zsh,我尝试在格式的外部usb驱动器上执行chmod。但是,它没有像预期的那样工作。为什么?