Skip to content

Commit 75bdf2c

Browse files
committed
is_writable: java much faster, with fallback
1 parent 2133449 commit 75bdf2c

File tree

5 files changed

+43
-23
lines changed

5 files changed

+43
-23
lines changed

+stdlib/+java/is_writable.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function y = is_writable(p)
2+
3+
% https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/nio/file/Files.html#isWritable(java.nio.file.Path)
4+
% java.nio.file.Files java is about 10x slower than fileattrib and needs absolute()
5+
% file = stdlib.absolute(file, "", false);
6+
% ok = java.nio.file.Files.isWritable(javaPathObject(file));
7+
8+
y = javaObject("java.io.File", p).canWrite();
9+
end

+stdlib/+native/is_writable.m

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function y = is_writable(p)
2+
3+
y = false;
4+
5+
if ~stdlib.exists(p), return, end
6+
7+
if ~isMATLABReleaseOlderThan('R2025a')
8+
9+
props = "Writable";
10+
if isunix
11+
props = [props, "GroupWrite", "OtherWrite"];
12+
end
13+
14+
t = getPermissions(filePermissions(p), props);
15+
y = t.Writable;
16+
17+
else
18+
a = stdlib.native.file_attributes(p);
19+
y = a.UserWrite || a.GroupWrite || a.OtherWrite;
20+
end
21+
22+
end

+stdlib/is_writable.m

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,15 @@
55
%% Outputs
66
% ok: logical array of the same size as p, true if file is writable
77

8-
function ok = is_writable(p)
8+
function y = is_writable(p)
99
arguments
10-
p string
10+
p {mustBeTextScalar}
1111
end
1212

13-
ok(size(p)) = false;
14-
15-
i = stdlib.exists(p);
16-
17-
if ~any(i), return, end
18-
19-
if ~isMATLABReleaseOlderThan('R2025a')
20-
21-
props = "Writable";
22-
if isunix
23-
props = [props, "GroupWrite", "OtherWrite"];
24-
end
25-
26-
t = getPermissions(filePermissions(p(i)), props);
27-
ok(i) = any(t{:,:}, 2);
28-
13+
if stdlib.has_java()
14+
y = stdlib.java.is_writable(p);
2915
else
30-
a = stdlib.native.file_attributes(p);
31-
ok = a.UserWrite || a.GroupWrite || a.OtherWrite;
16+
y = stdlib.native.is_writable(p);
3217
end
3318

3419
end
35-
%!assert (is_writable('is_writable.m'))

+stdlib/xcode_version.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
[s, m] = system('pkgutil --pkg-info com.apple.pkg.CLTools_Executables');
99
if s == 0
1010
v = regexp(m, '(?<=version:\s*)(\d+\.\d+(\.\d+)+)', 'match', 'once');
11+
else
12+
warning("stdlib:xcode_version:runtimeError", "%d failed to get Command Line Tools Xcode version", s)
1113
end
1214
end
1315

test/TestExists.m

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
}
1010
% on CI matlabroot can be writable!
1111
isr_fun = {@stdlib.is_readable, @stdlib.java.is_readable, @stdlib.native.is_readable}
12+
isw_fun = {@stdlib.is_writable, @stdlib.java.is_writable, @stdlib.native.is_writable}
1213
end
1314

1415
methods(TestClassSetup)
@@ -34,8 +35,10 @@ function test_is_readable(tc, Ps, isr_fun)
3435
end
3536

3637

37-
function test_is_writable(tc, Ps)
38-
ok = stdlib.is_writable(Ps{1});
38+
function test_is_writable(tc, Ps, isw_fun)
39+
is_capable(tc, isw_fun)
40+
41+
ok = isw_fun(Ps{1});
3942
tc.verifyEqual(ok, Ps{2}, Ps{1})
4043
end
4144

0 commit comments

Comments
 (0)