Properly close channel in SynchronossPart

This commit properly closes the opened channels in the SynchronossPart,
and also makes sure that the entire contents is copied, not just the
first batch.
This commit is contained in:
Arjen Poutsma 2017-05-03 14:44:48 +02:00
parent 27057889f8
commit cf7dfc7b17
2 changed files with 33 additions and 9 deletions

View File

@ -73,10 +73,10 @@ public interface Part {
/**
* Transfer the file in this part to the given file destination.
* @param dest the target file
* @param destination the target file
* @return completion {@code Mono} with the result of the file transfer,
* possibly {@link IllegalStateException} if the part isn't a file
*/
Mono<Void> transferTo(File dest);
Mono<Void> transferTo(File destination);
}

View File

@ -66,6 +66,7 @@ import org.springframework.util.StreamUtils;
*
* @author Sebastien Deleuze
* @author Rossen Stoyanchev
* @author Arjen Poutsma
* @since 5.0
* @see <a href="https://github.com/synchronoss/nio-multipart">Synchronoss NIO Multipart</a>
*/
@ -301,22 +302,45 @@ public class SynchronossMultipartHttpMessageReader implements HttpMessageReader<
}
@Override
public Mono<Void> transferTo(File dest) {
public Mono<Void> transferTo(File destination) {
if (this.storage == null || !getFilename().isPresent()) {
return Mono.error(new IllegalStateException("The part does not represent a file."));
}
ReadableByteChannel input = null;
FileChannel output = null;
try {
ReadableByteChannel ch = Channels.newChannel(this.storage.getInputStream());
long expected = (ch instanceof FileChannel ? ((FileChannel) ch).size() : Long.MAX_VALUE);
long actual = new FileOutputStream(dest).getChannel().transferFrom(ch, 0, expected);
if (actual < expected) {
return Mono.error(new IOException(
"Could only write " + actual + " out of " + expected + " bytes"));
input = Channels.newChannel(this.storage.getInputStream());
output = new FileOutputStream(destination).getChannel();
long size = (input instanceof FileChannel ? ((FileChannel) input).size() : Long.MAX_VALUE);
long totalWritten = 0;
while (totalWritten < size) {
long written = output.transferFrom(input, totalWritten, size - totalWritten);
if (written <= 0) {
break;
}
totalWritten += written;
}
}
catch (IOException ex) {
return Mono.error(ex);
}
finally {
if (input != null) {
try {
input.close();
}
catch (IOException ignored) {
}
}
if (output != null) {
try {
output.close();
}
catch (IOException ignored) {
}
}
}
return Mono.empty();
}
}