@Synchronized @Override public CompleteMultipartUploadResult completeMultipartUpload(CompleteMultipartUploadRequest request) { Map<Integer, CopyPartRequest> partMap = multipartUploads.get(request.getKey()); if (partMap == null) { throw new S3Exception("NoSuchKey", HttpStatus.SC_NOT_FOUND, "NoSuchKey", ""); } try { partMap.forEach((index, copyPart) -> { if (!copyPart.getKey().equals(copyPart.getSourceKey())) { Path sourcePath = Paths.get(this.baseDir, copyPart.getBucketName(), copyPart.getSourceKey()); Path targetPath = Paths.get(this.baseDir, copyPart.getBucketName(), copyPart.getKey()); try (FileChannel sourceChannel = FileChannel.open(sourcePath, StandardOpenOption.READ); FileChannel targetChannel = FileChannel.open(targetPath, StandardOpenOption.WRITE)) { targetChannel.transferFrom(sourceChannel, Files.size(targetPath), copyPart.getSourceRange().getLast() + 1 - copyPart.getSourceRange().getFirst()); targetChannel.close(); AclSize aclMap = this.aclMap.get(copyPart.getKey()); this.aclMap.put(copyPart.getKey(), aclMap.withSize(Files.size(targetPath))); } catch (IOException e) { throw new S3Exception("NoSuchKey", 404, "NoSuchKey", ""); } } }); } finally { multipartUploads.remove(request.getKey()); } return new CompleteMultipartUploadResult(); }