@@ -38,49 +38,69 @@ private Fallocate(FileChannel channel, int fd, long final_filesize) {
38
38
}
39
39
40
40
public static Fallocate forChannel (FileChannel channel , long final_filesize ) {
41
- return new Fallocate (channel , getDescriptor (channel ), final_filesize );
41
+ try {
42
+ return new Fallocate (channel , getDescriptor (channel ), final_filesize );
43
+ } catch (final UnsupportedOperationException exception ) {
44
+ // File descriptor is not supported: fd is null and unavailable
45
+ return new Fallocate (channel , 0 , final_filesize );
46
+ }
42
47
}
43
48
44
49
public static Fallocate forChannel (FileChannel channel , FileDescriptor fd , long final_filesize ) {
45
- return new Fallocate (channel , getDescriptor (fd ), final_filesize );
50
+ try {
51
+ return new Fallocate (channel , getDescriptor (fd ), final_filesize );
52
+ } catch (final UnsupportedOperationException exception ) {
53
+ // File descriptor is not supported: fd is null and unavailable
54
+ return new Fallocate (channel , 0 , final_filesize );
55
+ }
46
56
}
47
57
48
- public Fallocate fromOffset (long offset ) {
58
+ public Fallocate fromOffset (long offset ) throws IllegalArgumentException {
49
59
if (offset < 0 || offset > final_filesize ) throw new IllegalArgumentException ();
50
60
this .offset = offset ;
51
61
return this ;
52
62
}
53
63
54
- public Fallocate keepSize () {
64
+ public Fallocate keepSize () throws UnsupportedOperationException {
55
65
requireLinux ("fallocate keep size" );
56
66
mode |= FALLOC_FL_KEEP_SIZE ;
57
67
return this ;
58
68
}
59
69
60
- private void requireLinux (String feature ) {
70
+ private void requireLinux (String feature ) throws UnsupportedOperationException {
61
71
if (!IS_LINUX ) {
62
72
throwUnsupported (feature );
63
73
}
64
74
}
65
75
66
- private void throwUnsupported (String feature ) {
76
+ private void throwUnsupported (String feature ) throws UnsupportedOperationException {
67
77
throw new UnsupportedOperationException (feature + " is not supported on this file system" );
68
78
}
69
79
70
80
public void execute () throws IOException {
71
81
int errno = 0 ;
72
82
boolean isUnsupported = false ;
73
- if (IS_LINUX ) {
74
- final int result = FallocateHolder .fallocate (fd , mode , offset , final_filesize -offset );
75
- errno = result == 0 ? 0 : Native .getLastError ();
76
- } else if (IS_POSIX ) {
77
- errno = FallocateHolderPOSIX .posix_fallocate (fd , offset , final_filesize -offset );
83
+ if (fd != 0 ) {
84
+ if (IS_LINUX ) {
85
+ final int result = FallocateHolder .fallocate (fd , mode , offset , final_filesize -offset );
86
+ errno = result == 0 ? 0 : Native .getLastError ();
87
+ } else if (IS_POSIX ) {
88
+ errno = FallocateHolderPOSIX .posix_fallocate (fd , offset , final_filesize -offset );
89
+ } else {
90
+ isUnsupported = true ;
91
+ }
78
92
} else {
79
- isUnsupported = true ;
93
+ // fd is null and unavailable
94
+ if (Platform .isWindows ()) {
95
+ // Windows do not create sparse files by default, so just write a byte at the end.
96
+ channel .write (ByteBuffer .allocate (1 ), final_filesize - 1 );
97
+ } else {
98
+ isUnsupported = true ;
99
+ }
80
100
}
81
101
82
102
if (isUnsupported || errno != 0 ) {
83
- Logger .normal (this , "fallocate() failed; using legacy method; errno=" + errno );
103
+ Logger .normal (this , "fallocate() failed; using legacy method; errno=" + errno );
84
104
legacyFill (channel , final_filesize , offset );
85
105
}
86
106
}
@@ -101,7 +121,7 @@ private static class FallocateHolderPOSIX {
101
121
private static native int posix_fallocate (int fd , long offset , long length );
102
122
}
103
123
104
- private static int getDescriptor (FileChannel channel ) {
124
+ private static int getDescriptor (FileChannel channel ) throws UnsupportedOperationException {
105
125
try {
106
126
// sun.nio.ch.FileChannelImpl declares private final java.io.FileDescriptor fd
107
127
final Field field = channel .getClass ().getDeclaredField ("fd" );
@@ -112,7 +132,7 @@ private static int getDescriptor(FileChannel channel) {
112
132
}
113
133
}
114
134
115
- private static int getDescriptor (FileDescriptor descriptor ) {
135
+ private static int getDescriptor (FileDescriptor descriptor ) throws UnsupportedOperationException {
116
136
try {
117
137
// Oracle java.io.FileDescriptor declares private int fd
118
138
final Field field = descriptor .getClass ().getDeclaredField (IS_ANDROID ? "descriptor" : "fd" );
0 commit comments