How do you read file attributes (size, timestamps, type, POSIX permissions) with NIO.2, and what is the advantage of the attribute-views model?
answer
- readAttributes = one call for many attributes
- BasicFileAttributes portable; Posix/Dos OS-specific
- Views = portability + progressive enhancement
- Select by class token or string name ("posix:permissions")
- NOFOLLOW_LINKS inspects the link itself
- FileTime not raw millis
basics
~20 sUse the Files helpers like size(), isDirectory(), getLastModifiedTime(), or read a whole bundle with Files.readAttributes(path, BasicFileAttributes.class). For OS-specific data like Unix permissions you request a PosixFileAttributes view. One bulk read is cheaper than many separate calls.
solid answer
~40 sNIO.2 exposes file metadata through both convenience methods and a structured attribute-views model. Quick single queries: Files.size(p), Files.isDirectory(p), Files.isRegularFile(p), Files.getLastModifiedTime(p), Files.isSymbolicLink(p). For efficiency, Files.readAttributes(p, BasicFileAttributes.class) fetches size, creation/modified/access times, and type flags in one system call instead of several. The views model abstracts platform differences: BasicFileAttributes is portable everywhere; PosixFileAttributes (and PosixFileAttributeView) add owner, group, and rwx permissions on Unix-like systems; DosFileAttributes covers Windows hidden/readonly flags. You select by class token or name ("posix:permissions"). The advantage is portability with progressive enhancement: code reads the common subset uniformly, and platform-specific attributes are available only where supported, with NOFOLLOW_LINKS letting you inspect a symlink itself rather than its target.
go deeper
Can read basic facts like size and whether a path is a directory using Files helpers.
Knows readAttributes for bulk reads and that POSIX/DOS attributes are OS-specific.
Explains the views model (portable core + opt-in OS extensions), efficiency of bulk reads, NOFOLLOW_LINKS, and FileTime.
Designs portable file-metadata handling with capability checks (supportsFileAttributeView), and reasons about performance of attribute access in large traversals.
## Beyond existence: file metadata Every file carries **attributes** (metadata): its size, timestamps, whether it is a directory or a symlink, and on some systems ownership and permission bits. NIO.2 reads these in two complementary ways. ## Convenience methods on Files For a single fact, `Files` has direct helpers: ```java long bytes = Files.size(p); boolean dir = Files.isDirectory(p); boolean regular = Files.isRegularFile(p); FileTime mtime = Files.getLastModifiedTime(p); boolean link = Files.isSymbolicLink(p); boolean hidden = Files.isHidden(p); ``` These are readable but each one may perform its own underlying system call. ## Bulk read: readAttributes (the efficient path) If you need several attributes, ask for them **all at once**: ```java BasicFileAttributes a = Files.readAttributes(p, BasicFileAttributes.class); a.size(); a.creationTime(); a.lastModifiedTime(); a.isDirectory(); a.isSymbolicLink(); ``` This performs essentially **one** `stat`-style call and returns an immutable snapshot, which is far cheaper than calling `size()`, then `getLastModifiedTime()`, then `isDirectory()` separately (each a round trip). Prefer this whenever you read more than one attribute, especially inside a traversal over many files. ## The attribute-views model: portability with enhancement Different operating systems expose different metadata. NIO.2 models this as **attribute views**, each a typed bundle: - **BasicFileAttributes** — the portable core (size, times, type). Available on *every* file system. - **PosixFileAttributes** — adds `owner()`, `group()`, and a `Set<PosixFilePermission>` (the rwx bits) on POSIX/Unix-like systems. - **DosFileAttributes** — Windows DOS flags: hidden, read-only, system, archive. You select a view by its **class token** or by **string name**: ```java Set<PosixFilePermission> perms = Files.readAttributes(p, PosixFileAttributes.class).permissions(); // or by name: Object perm = Files.getAttribute(p, "posix:permissions"); ``` To *change* attributes you obtain an updatable **view**: ```java Files.setPosixFilePermissions(p, PosixFilePermissions.fromString("rw-r-----")); ``` ### Why views are a good design The views give you **portability with progressive enhancement**: your common logic reads `BasicFileAttributes` and runs everywhere; platform-specific needs (Unix permissions, Windows flags) are requested explicitly and only succeed where the file system supports them (`UnsupportedOperationException` otherwise). You check support with `fileStore.supportsFileAttributeView(...)` or `fileSystem.supportedFileAttributeViews()`. This avoids a lowest-common-denominator API while keeping the portable path clean. ## Symbolic links Attribute reads follow symbolic links **by default** (you see the *target's* metadata). Pass `LinkOption.NOFOLLOW_LINKS` to inspect the **link itself** — essential when you need to know whether something is a link, or to avoid being redirected. ## FileTime and time zones Timestamps come back as `FileTime`, a precise instant (it can convert to/from `Instant`), avoiding the ambiguity of the old `long` millis. ## Summary - One attribute → a `Files.isX/getX` helper. - Several attributes → `Files.readAttributes(..., BasicFileAttributes.class)` in one call. - Platform-specific data → the matching view (`PosixFileAttributes`, `DosFileAttributes`), requested explicitly. - The views model trades a single fat API for a portable core plus opt-in OS extensions.
- Why prefer Files.readAttributes over several individual Files.isX/getX calls?readAttributes fetches all the attributes in a single underlying stat call and returns an immutable snapshot, whereas each individual helper may issue its own system call. For multiple attributes — and especially in loops over many files — the bulk read is significantly cheaper.
- How do you read Unix permission bits, and what happens on a system that doesn't support them?Request the POSIX view: Files.readAttributes(p, PosixFileAttributes.class).permissions(), or Files.getAttribute(p, "posix:permissions"). On a non-POSIX file system the request throws UnsupportedOperationException; you can pre-check via fileStore.supportsFileAttributeView or supportedFileAttributeViews().
saying these in an interview costs you the question
- Calling size, then mtime, then isDirectory separately when one readAttributes would do
- Assuming POSIX permissions are available on every OS
- Forgetting attribute reads follow symlinks by default
- Treating BasicFileAttributes as mutable (it is a snapshot)