1212import java .nio .channels .FileLock ;
1313import java .nio .channels .ReadableByteChannel ;
1414import java .nio .channels .WritableByteChannel ;
15- import java .nio .file .FileAlreadyExistsException ;
16- import java .nio .file .NoSuchFileException ;
17- import java .nio .file .OpenOption ;
18- import java .nio .file .StandardOpenOption ;
15+ import java .nio .file .*;
1916import java .util .Collections ;
2017import java .util .HashSet ;
2118import java .util .Set ;
@@ -27,40 +24,38 @@ public class S3FileChannel extends FileChannel {
2724 private S3Path path ;
2825 private Set <? extends OpenOption > options ;
2926 private FileChannel filechannel ;
30- private File tempFile ;
27+ private Path tempFile ;
3128
3229 public S3FileChannel (S3Path path , Set <? extends OpenOption > options ) throws IOException {
3330 this .path = path ;
3431 this .options = Collections .unmodifiableSet (new HashSet <>(options ));
3532 String key = path .getKey ();
36- boolean existed = path .getFileSystem ().provider ().exists (path );
33+ boolean exists = path .getFileSystem ().provider ().exists (path );
3734
38- if (existed && this .options .contains (StandardOpenOption .CREATE_NEW ))
35+ if (exists && this .options .contains (StandardOpenOption .CREATE_NEW ))
3936 throw new FileAlreadyExistsException (format ("target already exists: %s" , path ));
40- else if (!existed
41- && !this .options .contains (StandardOpenOption .CREATE_NEW )
42- && !this .options .contains (StandardOpenOption .CREATE ))
37+ else if (!exists && !this .options .contains (StandardOpenOption .CREATE_NEW ) &&
38+ !this .options .contains (StandardOpenOption .CREATE ))
4339 throw new NoSuchFileException (format ("target not exists: %s" , path ));
4440
45- tempFile = File .createTempFile ("temp-s3-" , key .replaceAll ("/" , "_" ));
41+ tempFile = Files .createTempFile ("temp-s3-" , key .replaceAll ("/" , "_" ));
4642 boolean removeTempFile = true ;
4743 try {
48- if (existed && this . options . contains ( StandardOpenOption . READ ) ) {
44+ if (exists ) {
4945 try (S3Object object = path .getFileSystem ()
5046 .getClient ()
5147 .getObject (path .getFileStore ().getBucket ().getName (), key )) {
52- IOUtils .copy (object .getObjectContent (), new FileOutputStream ( tempFile ) );
48+ Files .copy (object .getObjectContent (), tempFile , StandardCopyOption . REPLACE_EXISTING );
5349 }
5450 }
55- if (this .options .contains (StandardOpenOption .READ )) {
56- filechannel = new FileInputStream (tempFile ).getChannel ();
57- } else {
58- filechannel = new FileOutputStream (tempFile ).getChannel ();
59- }
51+
52+ Set <? extends OpenOption > fileChannelOptions = new HashSet <>(this .options );
53+ fileChannelOptions .remove (StandardOpenOption .CREATE_NEW );
54+ filechannel = FileChannel .open (tempFile , fileChannelOptions );
6055 removeTempFile = false ;
6156 } finally {
6257 if (removeTempFile ) {
63- tempFile . delete ( );
58+ Files . deleteIfExists ( tempFile );
6459 }
6560 }
6661 }
@@ -150,16 +145,25 @@ protected void implCloseChannel() throws IOException {
150145 super .close ();
151146 filechannel .close ();
152147 if (!this .options .contains (StandardOpenOption .READ )) {
153- try (InputStream stream = new BufferedInputStream (new FileInputStream (tempFile ))) {
154- ObjectMetadata metadata = new ObjectMetadata ();
155- metadata .setContentLength (tempFile .length ());
156- metadata .setContentType (new Tika ().detect (stream , path .getFileName ().toString ()));
157-
158- String bucket = path .getFileStore ().name ();
159- String key = path .getKey ();
160- path .getFileSystem ().getClient ().putObject (bucket , key , stream , metadata );
161- }
148+ sync ();
149+ }
150+ Files .deleteIfExists (tempFile );
151+ }
152+
153+ /**
154+ * try to sync the temp file with the remote s3 path.
155+ *
156+ * @throws IOException if the tempFile fails to open a newInputStream
157+ */
158+ protected void sync () throws IOException {
159+ try (InputStream stream = new BufferedInputStream (Files .newInputStream (tempFile ))) {
160+ ObjectMetadata metadata = new ObjectMetadata ();
161+ metadata .setContentLength (Files .size (tempFile ));
162+ metadata .setContentType (new Tika ().detect (stream , path .getFileName ().toString ()));
163+
164+ String bucket = path .getFileStore ().name ();
165+ String key = path .getKey ();
166+ path .getFileSystem ().getClient ().putObject (bucket , key , stream , metadata );
162167 }
163- tempFile .delete ();
164168 }
165169}
0 commit comments