JDK-8215467 : Files.isHidden should return true for hidden directories on Windows
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 7,8,11,12
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2018-12-15
  • Updated: 2019-01-28
  • Resolved: 2019-01-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 13
13 b05Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Sub Tasks
JDK-8225153 :  
Description
ADDITIONAL SYSTEM INFORMATION :
OS: Windows 10 Home
Java: OpenJDK 11.0.1+13
File System: NTFS

A DESCRIPTION OF THE PROBLEM :
First, this issue is related/the-same-as two other issues: JDK-8029123 and JDK-8170334. Both were closed as "Not an issue". However, the behavior/contract of Files.isHidden appears inconsistent with other, core software on Windows such as File Explorer, CMD, and PowerShell.

In Windows one can mark a directory as hidden and it won't be displayed by File Explorer (unless configured to display hidden items). The directory won't even appear via CMD with "dir" or via PowerShell with "Get-ChildItem"; not unless explicitly requested by command-line options. Yet this same directory "isn't hidden" according to Files.isHidden.

There's a related question on Stack Overflow: https://stackoverflow.com/questions/53791740/why-does-files-ishiddenpath-return-false-for-directories-on-windows

An answer to that question points to documentation that indicates the hidden attribute relates to a file OR directory, not just a file. (Link to Windows documentation: https://docs.microsoft.com/en-us/windows/desktop/fileio/file-attribute-constants).

If Files.isHidden really is doing the correct thing, maybe it's possible to include documentation explaining why it doesn't behave the same as other Windows software?

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Single step: Call Files.isHidden with a Path that points to a hidden directory.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Files.isHidden returns true.
ACTUAL -
Files.isHidden returns false.

---------- BEGIN SOURCE ----------
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.DosFileAttributes;

public class Main {

  public static void main(String[] args) throws Exception {  
    final var directory = Path.of(args[0]).toAbsolutePath().normalize();
    final var store     = Files.getFileStore(directory);
    final var dosAttrs  = Files.readAttributes(directory, DosFileAttributes.class);

    System.out.println("Directory     : " + directory);
    System.out.println("FileStore     : " + store.name() + " [" + store.type() + "]");
    System.out.println("Hidden (Files): " + Files.isHidden(directory));
    System.out.println("Hidden (Dos)  : " + dosAttrs.isHidden());
  }

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Query the attribute via java.nio.file.attribute.DosFileAttributes#isHidden directly, rather than use Files.isHidden or the equivalent FileSystemProvider.isHidden.

FREQUENCY : always



Comments
Looks to me that for Windows folders the read-only attribute is meaningless but the hidden attribute has meaning. With a folder's read-only attribute set, it is possible to create and append to a file within that folder. This appears to be the case whether the read-only attribute is set on the folder either before or after the contained file is created and written to. The hidden attribute does appear to be meaningful as, unless explicitly configured to display hidden folders, Windows Explorer does not display them if the hidden attribute is set. Therefore I think that the lines // DOS hidden attribute not meaningful when set on directories if (attrs.isDirectory()) return false; can be removed from sun.nio.fs.WindowsFilsSystemProvider::isHidden().
15-01-2019

The DOS hidden or readonly attribute has historically been meaningless on directories. We need to check into this to make sure that they haven't been mixed up or whether Microsoft has changed the semantics of this attribute in recent releases. If it helps, and the submitter wants to read the value of the hidden attribute, then it can be done with code like this: boolean hidden = Files.getFileAttributeView(path, DosFileAttributeView.class).readAttributes().isHidden();
21-12-2018

I have not been able to find any information on Microsoft's having recently or ever changed the semantics of the hidden attribute for directories.
20-12-2018

Verified on Windows 7-x64 that this statement from the submitter is true "In Windows one can mark a directory as hidden and it won't be displayed by File Explorer (unless configured to display hidden items)." but Files.isHidden() returns false for such a directory. Also the behavior of File.isHidden() and Files.isHidden(Path) are inconsistent for a hidden directory although they are self-consistent with their respective javadoc specifications: Directory : C:\cygwin64\home\bburkhal\sbdata\bugs\hidden FileStore : System [NTFS] Hidden (java.nio.file.Files): false Hidden (Dos Attrs) : true Hidden (java.io.File): true
20-12-2018

Tested on JDK 12-ea + 21 on Windows 7 with the attached test case. JDK 12-ea+21 - Fail Output: Directory : D:\tmp\hide FileStore : Data [NTFS] Hidden (Files): false Hidden (Dos) : true
17-12-2018