Skip to content

Commit ed4bd43

Browse files
committed
Add writableChannel to WritableResource
This commit introduces a `writableChannel()` method to `WritableResource`, defaulting to `Channels.newChannel`, but with overrides for file-based resources.
1 parent 9d8e9cf commit ed4bd43

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
2525
import java.net.URI;
2626
import java.net.URL;
2727
import java.nio.channels.ReadableByteChannel;
28+
import java.nio.channels.WritableByteChannel;
2829

2930
import org.springframework.util.Assert;
3031
import org.springframework.util.StringUtils;
@@ -178,6 +179,15 @@ public ReadableByteChannel readableChannel() throws IOException {
178179
return new FileInputStream(this.file).getChannel();
179180
}
180181

182+
/**
183+
* This implementation opens a FileChannel for the underlying file.
184+
* @see java.nio.channels.FileChannel
185+
*/
186+
@Override
187+
public WritableByteChannel writableChannel() throws IOException {
188+
return new FileOutputStream(this.file).getChannel();
189+
}
190+
181191
/**
182192
* This implementation returns the underlying File's length.
183193
*/

spring-core/src/main/java/org/springframework/core/io/PathResource.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
2424
import java.net.URI;
2525
import java.net.URL;
2626
import java.nio.channels.ReadableByteChannel;
27+
import java.nio.channels.WritableByteChannel;
2728
import java.nio.file.Files;
2829
import java.nio.file.OpenOption;
2930
import java.nio.file.Path;
@@ -197,14 +198,23 @@ public File getFile() throws IOException {
197198
}
198199

199200
/**
200-
* This implementation opens a InputStream for the underlying file.
201-
* @see java.nio.file.spi.FileSystemProvider#newInputStream(Path, OpenOption...)
201+
* This implementation opens a Channel for the underlying file.
202+
* @see Files#newByteChannel(Path, OpenOption...)
202203
*/
203204
@Override
204205
public ReadableByteChannel readableChannel() throws IOException {
205206
return Files.newByteChannel(this.path, StandardOpenOption.READ);
206207
}
207208

209+
/**
210+
* This implementation opens a Channel for the underlying file.
211+
* @see Files#newByteChannel(Path, OpenOption...)
212+
*/
213+
@Override
214+
public WritableByteChannel writableChannel() throws IOException {
215+
return Files.newByteChannel(this.path, StandardOpenOption.WRITE);
216+
}
217+
208218
/**
209219
* This implementation returns the underlying File's length.
210220
*/

spring-core/src/main/java/org/springframework/core/io/WritableResource.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
1818

1919
import java.io.IOException;
2020
import java.io.OutputStream;
21+
import java.nio.channels.Channels;
22+
import java.nio.channels.WritableByteChannel;
2123

2224
/**
2325
* Extended interface for a resource that supports writing to it.
@@ -51,4 +53,19 @@ default boolean isWritable() {
5153
*/
5254
OutputStream getOutputStream() throws IOException;
5355

56+
/**
57+
* Return a {@link WritableByteChannel}.
58+
* <p>It is expected that each call creates a <i>fresh</i> channel.
59+
* <p>The default implementation returns {@link Channels#newChannel(OutputStream)}
60+
* with the result of {@link #getOutputStream()}.
61+
* @return the byte channel for the underlying resource (must not be {@code null})
62+
* @throws java.io.FileNotFoundException if the underlying resource doesn't exist
63+
* @throws IOException if the content channel could not be opened
64+
* @since 5.0
65+
* @see #getOutputStream()
66+
*/
67+
default WritableByteChannel writableChannel() throws IOException {
68+
return Channels.newChannel(getOutputStream());
69+
}
70+
5471
}

spring-core/src/test/java/org/springframework/core/io/PathResourceTests.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,6 +21,8 @@
2121
import java.net.URI;
2222
import java.nio.ByteBuffer;
2323
import java.nio.channels.ReadableByteChannel;
24+
import java.nio.channels.WritableByteChannel;
25+
import java.nio.charset.StandardCharsets;
2426
import java.nio.file.AccessDeniedException;
2527
import java.nio.file.NoSuchFileException;
2628
import java.nio.file.Path;
@@ -272,7 +274,7 @@ public void directoryIsNotWritable() throws Exception {
272274
@Test
273275
public void outputStream() throws Exception {
274276
PathResource resource = new PathResource(temporaryFolder.newFile("test").toPath());
275-
FileCopyUtils.copy("test".getBytes(), resource.getOutputStream());
277+
FileCopyUtils.copy("test".getBytes(StandardCharsets.UTF_8), resource.getOutputStream());
276278
assertThat(resource.contentLength(), equalTo(4L));
277279
}
278280

@@ -328,4 +330,21 @@ public void getReadableByteChannelDoesNotExist() throws Exception {
328330
resource.readableChannel();
329331
}
330332

333+
@Test
334+
public void getWritableChannel() throws Exception {
335+
PathResource resource = new PathResource(temporaryFolder.newFile("test").toPath());
336+
ByteBuffer buffer = ByteBuffer.wrap("test".getBytes(StandardCharsets.UTF_8));
337+
WritableByteChannel channel = null;
338+
try {
339+
channel = resource.writableChannel();
340+
channel.write(buffer);
341+
}
342+
finally {
343+
if (channel != null) {
344+
channel.close();
345+
}
346+
}
347+
assertThat(resource.contentLength(), equalTo(4L));
348+
}
349+
331350
}

0 commit comments

Comments
 (0)