1010import java .util .Scanner ;
1111import java .io .File ;
1212import java .nio .file .Path ;
13+ import java .nio .file .Paths ;
14+ import java .nio .file .attribute .BasicFileAttributes ;
15+ import java .nio .file .attribute .DosFileAttributes ;
16+ import java .nio .file .LinkOption ;
1317
1418
1519public class Filesystem {
@@ -59,6 +63,12 @@ public static void main(String[] argv) {
5963 System .out .println (new File (a1 ).isFile ());
6064 } else if (command .equals ("is_readable" )) {
6165 System .out .println (is_readable (a1 ));
66+ } else if (command .equals ("is_reparse_point" )) {
67+ System .out .println (is_reparse_point (a1 ));
68+ } else if (command .equals ("is_writable" )) {
69+ System .out .println (is_writable (a1 ));
70+ } else if (command .equals ("is_symlink" )) {
71+ System .out .println (is_symlink (a1 ));
6272 } else if (command .equals ("ram_free" )) {
6373 System .out .println (ram_free ());
6474 } else if (command .equals ("cpu_count" )) {
@@ -78,9 +88,13 @@ public static String absolute(String path) {
7888 return f .getAbsolutePath ();
7989 }
8090
81- public static Boolean create_symlink (String target , String link ) {
82- Path t = new File (target ).toPath ();
83- Path l = new File (link ).toPath ();
91+ public static boolean is_windows () {
92+ return System .getProperty ("os.name" ).toLowerCase ().contains ("windows" );
93+ }
94+
95+ public static boolean create_symlink (String target , String link ) {
96+ Path t = Paths .get (target );
97+ Path l = Paths .get (link );
8498 try {
8599 java .nio .file .Files .createSymbolicLink (l , t );
86100 return true ;
@@ -106,27 +120,63 @@ public static String canonical(String path) {
106120 }
107121 }
108122
109- public static Boolean is_absolute (String path ) {
123+ public static boolean is_absolute (String path ) {
110124 return new File (path ).isAbsolute ();
111125 }
112126
113- public static Boolean is_exe (String path ) {
127+ public static boolean is_exe (String path ) {
114128 File f = new File (path );
115129 return f .canExecute ();
116130 }
117131
118- public static Boolean is_readable (String path ) {
132+ public static boolean is_readable (String path ) {
119133 return new File (path ).canRead ();
120134 }
121135
136+ public static boolean is_writable (String path ) {
137+ return new File (path ).canWrite ();
138+ }
139+
140+ public static boolean is_symlink (String path ) {
141+ Path p = Paths .get (path );
142+ return java .nio .file .Files .isSymbolicLink (p );
143+ }
144+
145+ public static boolean is_reparse_point (String path ) {
146+ // https://github.com/openjdk/jdk/blob/master/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java
147+ // reflection to access WindowsFileAttributes
148+ // https://stackoverflow.com/a/29647840
149+ if (!is_windows ()) {
150+ return false ;
151+ }
152+
153+ Path p = Paths .get (path );
154+ try {
155+ BasicFileAttributes attrs = java .nio .file .Files .readAttributes (p , BasicFileAttributes .class , LinkOption .NOFOLLOW_LINKS );
156+ if (DosFileAttributes .class .isInstance (attrs )) {
157+ java .lang .reflect .Method m = attrs .getClass ().getDeclaredMethod ("isReparsePoint" );
158+ m .setAccessible (true );
159+ return (boolean ) m .invoke (attrs );
160+ }
161+ } catch (Exception e ) {
162+ System .err .println (e );
163+ System .err .println ("Try running with --add-opens java.base/sun.nio.fs=ALL-UNNAMED" );
164+ }
165+ return false ;
166+ }
167+
168+
122169 public static String parent (String path ) {
123170 File f = new File (path );
124171 return f .getParent ();
125172 }
126173
127174 public static String root (String path ) {
128- File f = new File (path );
129- return f .toPath ().getRoot ().toString ();
175+ Path r = Paths .get (path ).getRoot ();
176+ if (r == null ) {
177+ return "" ;
178+ }
179+ return r .toString ();
130180 }
131181
132182 public static Long ram_free () {
0 commit comments