Add Resource.readableChannel()
Added readableChannel() to Resource, which returns a java.nio.ReadableByteChannel. The default implementation uses Channels.newChannel() to create a channel based on what is returned from getInputStream(). Subclasses have more effecient, file-based implementations. Issue: SPR-14698
This commit is contained in:
committed by
Rossen Stoyanchev
parent
06395f41cb
commit
c6a61e0d85
@@ -17,7 +17,7 @@
|
||||
package org.springframework.core.codec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Map;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
@@ -66,8 +66,8 @@ public class ResourceEncoder extends AbstractSingleValueEncoder<Resource> {
|
||||
protected Flux<DataBuffer> encode(Resource resource, DataBufferFactory dataBufferFactory,
|
||||
ResolvableType type, MimeType mimeType, Map<String, Object> hints) throws IOException {
|
||||
|
||||
InputStream is = resource.getInputStream();
|
||||
return DataBufferUtils.read(is, dataBufferFactory, bufferSize);
|
||||
ReadableByteChannel channel = resource.readableChannel();
|
||||
return DataBufferUtils.read(channel, dataBufferFactory, bufferSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
package org.springframework.core.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
@@ -115,6 +117,22 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
|
||||
return ResourceUtils.getFile(uri, getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation returns a FileChannel for the given URI-identified
|
||||
* resource, provided that it refers to a file in the file system.
|
||||
* @since 5.0
|
||||
* @see #getFile(URI)
|
||||
*/
|
||||
@Override
|
||||
public ReadableByteChannel readableChannel() throws IOException {
|
||||
if (isFile()) {
|
||||
return new FileInputStream(getFile()).getChannel();
|
||||
}
|
||||
else {
|
||||
return super.readableChannel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
import org.springframework.core.NestedIOException;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -122,6 +124,15 @@ public abstract class AbstractResource implements Resource {
|
||||
throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation returns {@link Channels#newChannel(InputStream)} with the result of
|
||||
* {@link #getInputStream()}.
|
||||
*/
|
||||
@Override
|
||||
public ReadableByteChannel readableChannel() throws IOException {
|
||||
return Channels.newChannel(getInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation reads the entire InputStream to calculate the
|
||||
* content length. Subclasses will almost always be able to provide
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -168,6 +169,15 @@ public class FileSystemResource extends AbstractResource implements WritableReso
|
||||
return this.file;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation opens a FileChannel for the underlying file.
|
||||
* @see java.nio.channels.FileChannel
|
||||
*/
|
||||
@Override
|
||||
public ReadableByteChannel readableChannel() throws IOException {
|
||||
return new FileInputStream(this.file).getChannel();
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation returns the underlying File's length.
|
||||
*/
|
||||
|
||||
@@ -23,10 +23,12 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.OpenOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -194,6 +196,15 @@ 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...)
|
||||
*/
|
||||
@Override
|
||||
public ReadableByteChannel readableChannel() throws IOException {
|
||||
return Files.newByteChannel(this.path, StandardOpenOption.READ);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation returns the underlying File's length.
|
||||
*/
|
||||
|
||||
@@ -18,8 +18,11 @@ package org.springframework.core.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
/**
|
||||
* Interface for a resource descriptor that abstracts from the actual
|
||||
@@ -111,6 +114,19 @@ public interface Resource extends InputStreamSource {
|
||||
*/
|
||||
File getFile() throws IOException;
|
||||
|
||||
/**
|
||||
* Return a {@link ReadableByteChannel}.
|
||||
* <p>It is expected that each call creates a <i>fresh</i> channel.
|
||||
* <p>The default implementation returns {@link Channels#newChannel(InputStream)} with the
|
||||
* result of {@link #getInputStream()}.
|
||||
* @return the byte channel for the underlying resource (must not be {@code null})
|
||||
* @throws IOException if the channel could not be opened
|
||||
* @since 5.0
|
||||
*/
|
||||
default ReadableByteChannel readableChannel() throws IOException {
|
||||
return Channels.newChannel(getInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the content length for this resource.
|
||||
* @throws IOException if the resource cannot be resolved
|
||||
|
||||
Reference in New Issue
Block a user