1515
1616package com .spectralogic .ds3client .helpers ;
1717
18+ import com .google .common .util .concurrent .Striped ;
1819import com .spectralogic .ds3client .helpers .Ds3ClientHelpers .ObjectChannelBuilder ;
1920import com .spectralogic .ds3client .utils .FileUtils ;
2021
2425import java .nio .file .Files ;
2526import java .nio .file .Path ;
2627import java .nio .file .StandardOpenOption ;
28+ import java .util .concurrent .locks .Lock ;
2729
2830/**
2931 * Writes files to the local file system preserving the path.
3032 */
3133public class FileObjectGetter implements ObjectChannelBuilder {
3234 private final Path root ;
35+ private final Striped <Lock > striped ;
3336
3437 /**
3538 * Creates a new FileObjectGetter to retrieve files from a remote DS3 system to the local file system.
39+ *
3640 * @param root The {@code root} directory of the local file system for all files being transferred.
3741 */
3842 public FileObjectGetter (final Path root ) {
3943 this .root = root ;
44+ this .striped = Striped .lazyWeakLock (10 );
4045 }
4146
4247 @ Override
@@ -47,14 +52,28 @@ public SeekableByteChannel buildChannel(final String key) throws IOException {
4752 Files .createDirectories (FileUtils .resolveForSymbolic (parentPath ));
4853 }
4954
50- if ( ! FileUtils .isTransferablePath (objectPath )) {
55+ if (! FileUtils .isTransferablePath (objectPath )) {
5156 throw new UnrecoverableIOException (objectPath + " is not a regular file." );
5257 }
5358
59+ final Lock lock = striped .get (key );
60+ try {
61+ lock .lock ();
62+ if (Files .notExists (objectPath )) {
63+ Files .createDirectories (objectPath .getParent ());
64+ return FileChannel .open (
65+ objectPath ,
66+ StandardOpenOption .SPARSE ,
67+ StandardOpenOption .WRITE ,
68+ StandardOpenOption .CREATE_NEW
69+ );
70+ }
71+ } finally {
72+ lock .unlock ();
73+ }
5474 return FileChannel .open (
5575 objectPath ,
56- StandardOpenOption .WRITE ,
57- StandardOpenOption .CREATE
76+ StandardOpenOption .WRITE
5877 );
5978 }
60- }
79+ }
0 commit comments