2

I have a special use case where I need to verify if a file is a special block file (only if my java program is run on Linux). My code can already detect if it's ran on Windows or Linux, so if it's windows I simply invalidate the verification.

For Linux, I was reading about the different FileAttributeView interfaces; and the first thing that popped up was to use the PosixFileAttributeView (since block and char device files are Linux-specific), but after looking further into its Javadoc, it only gives access to the different RWX (read, write, execute permissions relative to the owner, group and others) but nothing about special block files or other file attributes. On the other hand, the BasicFileAttributeView is supported by all filesystems and has an instance method called isOther(), this could work but there has to be some other way that's more specific than just knowing that a file is not a regular file, directory or symlink. Knowing that it's something other is just too vague.. Any help is deeply appreciated.

Lorenzo
  • 591
  • 7
  • 18

1 Answers1

1

Wow, this is actually harder than I imagined!

To ground this in Linux, what you're looking for is the st_mode field from stat() system call (in C-world). Its different values indicate whether the file is a character device, block device, directory, etc... The first character on each line of the return from ls -la represent that field: b for block device, d for directory, - for regular file, and on. For example, if you run ls -la /dev/sda you'll probably get something like brw-rw---- 1..., because sda is a block device. The first line of ls -la /opt will be dr-xr-xrx... since opt is a directory.

(https://linux.die.net/man/2/stat, for reference)

Poking around the Javadocs, I didn't find a file class that allows direct access to this st_mode field. Like you mentioned, there are methods to determine if the file is a directory, file, or other, but this is not sufficient to distinguish between all the options and figure out if it's a block device.

I did find this project which looks like it lets you get at that stat() struct in Java. It is a fair bit of overhead. Perhaps you could extract the bits you need for this application, but it might not be trivial. The specific method you'd need to call is isBlockDev()

Hope that helps a little bit, curious to see if you figure something out, or if there's a better answer out there!

Ben Gillett
  • 376
  • 1
  • 9
  • 1
    Yeah I've struggled my fair share before i decided to post a question about it >.<, the problem is that if i'm using an extra project/dependency, i could simply just do some kind of `Runtime.exec("ls")` or other and just parse the output myself ? But as you've mentioned, since it's platform dependent I guess there doesn't seem to be a native way of doing that in java.. – Lorenzo Jun 18 '20 at 16:23
  • A cleaner solution could be to just write the C code that does the system call and use JNI to retrieve an equivalent java statx structure ? But seems like too much work for checking a single attribute – Lorenzo Jun 18 '20 at 16:49
  • I upvoted your post but i'm not sure if i should mark it as the actual answer ? You did actually give me a valid solution using the library you proposed =o I was just hoping i'd be able to find a solution that might be more manual [and with less dependencies maybe] (like reading the first magic bytes of a file to determine it's type) but i'm not sure about if it's possible with block and char devices. – Lorenzo Jun 22 '20 at 02:34