mirror of
https://github.com/apache/jclouds.git
synced 2025-02-17 15:35:44 +00:00
Use the same file handle in file system getBlob
Previously getBlob lazily returned a ByteSource which could return a different content length than the blob metadata. Instead eagerly open a FileInputStream for consistency. Note that this has some consequences for LocalBlobStore.getBlob when used with ranges.
This commit is contained in:
parent
b7f28f1e6a
commit
aae0844cdf
@ -36,7 +36,9 @@ import static org.jclouds.filesystem.util.Utils.setPrivate;
|
|||||||
import static org.jclouds.filesystem.util.Utils.setPublic;
|
import static org.jclouds.filesystem.util.Utils.setPublic;
|
||||||
import static org.jclouds.util.Closeables2.closeQuietly;
|
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -377,8 +379,10 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
|
|||||||
BlobBuilder builder = blobBuilders.get();
|
BlobBuilder builder = blobBuilders.get();
|
||||||
builder.name(key);
|
builder.name(key);
|
||||||
File file = getFileForBlobKey(container, key);
|
File file = getFileForBlobKey(container, key);
|
||||||
|
InputStream is;
|
||||||
ByteSource byteSource;
|
ByteSource byteSource;
|
||||||
boolean isDirectory = false;
|
boolean isDirectory = false;
|
||||||
|
long length;
|
||||||
|
|
||||||
if (getDirectoryBlobSuffix(key) != null) {
|
if (getDirectoryBlobSuffix(key) != null) {
|
||||||
if (!file.isDirectory()) {
|
if (!file.isDirectory()) {
|
||||||
@ -391,8 +395,20 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
|
|||||||
logger.debug("%s - %s is a directory", container, key);
|
logger.debug("%s - %s is a directory", container, key);
|
||||||
byteSource = ByteSource.empty();
|
byteSource = ByteSource.empty();
|
||||||
isDirectory = true;
|
isDirectory = true;
|
||||||
|
length = 0;
|
||||||
|
is = new ByteArrayInputStream(new byte[0]);
|
||||||
} else {
|
} else {
|
||||||
byteSource = Files.asByteSource(file);
|
byteSource = Files.asByteSource(file);
|
||||||
|
try {
|
||||||
|
// Must operate only an open file handle to avoid concurrent putBlob changing the object
|
||||||
|
FileInputStream fis = new FileInputStream(file);
|
||||||
|
length = fis.getChannel().size();
|
||||||
|
is = fis;
|
||||||
|
} catch (FileNotFoundException fnfe) {
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String cacheControl = null;
|
String cacheControl = null;
|
||||||
@ -406,6 +422,7 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
|
|||||||
Tier tier = Tier.STANDARD;
|
Tier tier = Tier.STANDARD;
|
||||||
ImmutableMap.Builder<String, String> userMetadata = ImmutableMap.builder();
|
ImmutableMap.Builder<String, String> userMetadata = ImmutableMap.builder();
|
||||||
|
|
||||||
|
// TODO: not atomic -- how to read from the FileChannel?
|
||||||
UserDefinedFileAttributeView view = getUserDefinedFileAttributeView(file.toPath());
|
UserDefinedFileAttributeView view = getUserDefinedFileAttributeView(file.toPath());
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
try {
|
try {
|
||||||
@ -455,12 +472,12 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
|
|||||||
logger.debug("xattrs not supported on %s", file.toPath());
|
logger.debug("xattrs not supported on %s", file.toPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.payload(byteSource)
|
builder.payload(is)
|
||||||
.cacheControl(cacheControl)
|
.cacheControl(cacheControl)
|
||||||
.contentDisposition(contentDisposition)
|
.contentDisposition(contentDisposition)
|
||||||
.contentEncoding(contentEncoding)
|
.contentEncoding(contentEncoding)
|
||||||
.contentLanguage(contentLanguage)
|
.contentLanguage(contentLanguage)
|
||||||
.contentLength(byteSource.size())
|
.contentLength(length)
|
||||||
.contentMD5(hashCode)
|
.contentMD5(hashCode)
|
||||||
.eTag(eTag)
|
.eTag(eTag)
|
||||||
.contentType(contentType)
|
.contentType(contentType)
|
||||||
@ -469,8 +486,9 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
|
|||||||
.type(isDirectory ? StorageType.FOLDER : StorageType.BLOB)
|
.type(isDirectory ? StorageType.FOLDER : StorageType.BLOB)
|
||||||
.userMetadata(userMetadata.build());
|
.userMetadata(userMetadata.build());
|
||||||
} else {
|
} else {
|
||||||
builder.payload(byteSource)
|
builder.payload(is)
|
||||||
.contentLength(byteSource.size())
|
.contentLength(length)
|
||||||
|
// TODO: not atomic and expensive for large objects
|
||||||
.contentMD5(byteSource.hash(Hashing.md5()).asBytes());
|
.contentMD5(byteSource.hash(Hashing.md5()).asBytes());
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException fnfe) {
|
} catch (FileNotFoundException fnfe) {
|
||||||
@ -480,8 +498,9 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
|
|||||||
}
|
}
|
||||||
Blob blob = builder.build();
|
Blob blob = builder.build();
|
||||||
blob.getMetadata().setContainer(container);
|
blob.getMetadata().setContainer(container);
|
||||||
|
// TODO: not atomic
|
||||||
blob.getMetadata().setLastModified(new Date(file.lastModified()));
|
blob.getMetadata().setLastModified(new Date(file.lastModified()));
|
||||||
blob.getMetadata().setSize(file.length());
|
blob.getMetadata().setSize(length);
|
||||||
if (blob.getPayload().getContentMetadata().getContentMD5() != null)
|
if (blob.getPayload().getContentMetadata().getContentMD5() != null)
|
||||||
blob.getMetadata().setETag(base16().lowerCase().encode(blob.getPayload().getContentMetadata().getContentMD5()));
|
blob.getMetadata().setETag(base16().lowerCase().encode(blob.getPayload().getContentMetadata().getContentMD5()));
|
||||||
return blob;
|
return blob;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user