How do you filter hidden files using DirectoryStream.Filter

孤街浪徒 提交于 2021-02-09 08:20:06

问题


I am trying to filter hidden files using the NIO classes.

When I run the attached code on Windows 10 I get the following output:

Files:
        c:\Documents and Settings
        c:\PerfLogs
        c:\Program Files
        c:\Program Files (x86)
        c:\Users
        c:\Windows

Paths:
        c:\$Recycle.Bin
        c:\Config.Msi
        c:\Documents and Settings
        c:\Intel
        c:\IntelOptaneData
        c:\OEM
        c:\OneDriveTemp
        c:\PerfLogs
        c:\Program Files
        c:\Program Files (x86)
        c:\ProgramData
        c:\Recovery
        c:\System Volume Information
        c:\Users
        c:\Windows

The list displayed under Files (using the old File.listFiles(FileFilter) method) is the list I see in Windows File Explorer and is what I am expecting to see (except for the Document and Setting and I know how to fix that)

  1. Why is the NIO approach not filtering hidden files the same way?
  2. How do I get NIO filtering to be the same?

Here is the test code:

import java.io.*;
import java.nio.file.*;

public class ListFilesNIO
{
    public static void main(String[] args) throws Exception
    {
        String directory = "c:\\";

        //  Use old File I/O

        FileFilter fileFilter = new FileFilter()
        {
            @Override
            public boolean accept(File entry)
            {
                if (entry.isHidden()) return false;

                return true;
            }
        };

        System.out.println("Files:");
        File[] files = new File( directory ).listFiles( fileFilter );

        for (File file : files)
        {
            System.out.println( "\t" + file );
        }

        //  Use NIO

        DirectoryStream.Filter<Path> pathFilter = new DirectoryStream.Filter<Path>()
        {
            @Override
            public boolean accept(Path entry) throws IOException
            {
                if (Files.isHidden( entry )) return false;

                return true;
            }
        };

        System.out.println();
        System.out.println("Paths:");
        DirectoryStream<Path> paths = Files.newDirectoryStream(Paths.get( directory ), pathFilter);

        for (Path path : paths)
        {
            System.out.println( "\t" + path );
        }
    }
}

Note: when I run the code without the filter, in both cases 18 files are displayed. So the first approach is filtering 12 hidden files and the second approach is only filtering 3 files.


回答1:


It's not a bug but a feature(!) known since jdk7, Windows hidden directory are not detected as hidden, see this bug and this one (fix jdk13).

As a workaround, you can do this :

import java.nio.file.attribute.DosFileAttributes;
...
DirectoryStream.Filter<Path> pathFilter = new DirectoryStream.Filter<Path>()
        {
            @Override
            public boolean accept(Path entry) throws IOException
            {
               DosFileAttributes attr = Files.readAttributes(entry, DosFileAttributes.class);
               return !attr.isHidden();
            }
        };



回答2:


I ended up using:

DirectoryStream.Filter<Path> pathFilter = new DirectoryStream.Filter<Path>()
{
    @Override
    public boolean accept(Path entry) throws IOException
    {
        DosFileAttributes attr = Files.readAttributes(entry, DosFileAttributes.class, LinkOption.NOFOLLOW_LINKS);

        return !attr.isHidden();
    }
};

As I mentioned in my question, I also want the Documents and Settings to be hidden.

The Documents and Settings is a link to C:\Users.

The default implementation for the Files.readAttributes(…) method is to follow links. So I guess because the c:\Users directory is not hidden, the Documents and Settings is also considered not hidden.

By using LinkOption.NOFOLLOW_LINKS it is considered hidden, which is what I want.



来源:https://stackoverflow.com/questions/61785056/how-do-you-filter-hidden-files-using-directorystream-filter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!