Add writableChannel to WritableResource

This commit introduces a `writableChannel()` method to
`WritableResource`, defaulting to `Channels.newChannel`, but with
overrides for file-based resources.
This commit is contained in:
Arjen Poutsma 2017-05-03 11:19:55 +02:00
parent 9d8e9cf243
commit ed4bd43cac
4 changed files with 63 additions and 7 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -25,6 +25,7 @@ import java.io.OutputStream;
import java.net.URI;
import java.net.URL;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@ -178,6 +179,15 @@ public class FileSystemResource extends AbstractResource implements WritableReso
return new FileInputStream(this.file).getChannel();
}
/**
* This implementation opens a FileChannel for the underlying file.
* @see java.nio.channels.FileChannel
*/
@Override
public WritableByteChannel writableChannel() throws IOException {
return new FileOutputStream(this.file).getChannel();
}
/**
* This implementation returns the underlying File's length.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@ import java.io.OutputStream;
import java.net.URI;
import java.net.URL;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
@ -197,14 +198,23 @@ public class PathResource extends AbstractResource implements WritableResource {
}
/**
* This implementation opens a InputStream for the underlying file.
* @see java.nio.file.spi.FileSystemProvider#newInputStream(Path, OpenOption...)
* This implementation opens a Channel for the underlying file.
* @see Files#newByteChannel(Path, OpenOption...)
*/
@Override
public ReadableByteChannel readableChannel() throws IOException {
return Files.newByteChannel(this.path, StandardOpenOption.READ);
}
/**
* This implementation opens a Channel for the underlying file.
* @see Files#newByteChannel(Path, OpenOption...)
*/
@Override
public WritableByteChannel writableChannel() throws IOException {
return Files.newByteChannel(this.path, StandardOpenOption.WRITE);
}
/**
* This implementation returns the underlying File's length.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,6 +18,8 @@ package org.springframework.core.io;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
/**
* Extended interface for a resource that supports writing to it.
@ -51,4 +53,19 @@ public interface WritableResource extends Resource {
*/
OutputStream getOutputStream() throws IOException;
/**
* Return a {@link WritableByteChannel}.
* <p>It is expected that each call creates a <i>fresh</i> channel.
* <p>The default implementation returns {@link Channels#newChannel(OutputStream)}
* with the result of {@link #getOutputStream()}.
* @return the byte channel for the underlying resource (must not be {@code null})
* @throws java.io.FileNotFoundException if the underlying resource doesn't exist
* @throws IOException if the content channel could not be opened
* @since 5.0
* @see #getOutputStream()
*/
default WritableByteChannel writableChannel() throws IOException {
return Channels.newChannel(getOutputStream());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,8 @@ import java.io.FileNotFoundException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.AccessDeniedException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
@ -272,7 +274,7 @@ public class PathResourceTests {
@Test
public void outputStream() throws Exception {
PathResource resource = new PathResource(temporaryFolder.newFile("test").toPath());
FileCopyUtils.copy("test".getBytes(), resource.getOutputStream());
FileCopyUtils.copy("test".getBytes(StandardCharsets.UTF_8), resource.getOutputStream());
assertThat(resource.contentLength(), equalTo(4L));
}
@ -328,4 +330,21 @@ public class PathResourceTests {
resource.readableChannel();
}
@Test
public void getWritableChannel() throws Exception {
PathResource resource = new PathResource(temporaryFolder.newFile("test").toPath());
ByteBuffer buffer = ByteBuffer.wrap("test".getBytes(StandardCharsets.UTF_8));
WritableByteChannel channel = null;
try {
channel = resource.writableChannel();
channel.write(buffer);
}
finally {
if (channel != null) {
channel.close();
}
}
assertThat(resource.contentLength(), equalTo(4L));
}
}