Skip to content

Commit 6feaea2

Browse files
authored
Merge pull request #11 from raphaelheinz/android-close-stream
Android: Close input and output streams
2 parents fc86f09 + 24ee476 commit 6feaea2

File tree

1 file changed

+42
-117
lines changed

1 file changed

+42
-117
lines changed

android/src/main/java/com/drpogodin/reactnativefs/ReactNativeFsModule.java

+42-117
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
3838

3939
import java.io.ByteArrayOutputStream;
40+
import java.io.Closeable;
4041
import java.io.File;
4142
import java.io.FileInputStream;
4243
import java.io.FileNotFoundException;
@@ -63,6 +64,18 @@ public class ReactNativeFsModule extends ReactNativeFsSpec {
6364
private ArrayDeque<Promise> pendingPickFilePromises = new ArrayDeque<Promise>();
6465
private ActivityResultLauncher<String[]> pickFileLauncher;
6566

67+
/**
68+
* Attempts to close given object, discarting possible exception. Does nothing
69+
* if given argument is null.
70+
* @param closeable
71+
*/
72+
static private void closeIgnoringException(Closeable closeable) {
73+
if (closeable != null) {
74+
try { closeable.close(); }
75+
catch (Exception e) {}
76+
}
77+
}
78+
6679
ReactNativeFsModule(ReactApplicationContext context) {
6780
super(context);
6881

@@ -137,12 +150,9 @@ public void addListener(String eventName) {
137150

138151
@ReactMethod
139152
public void appendFile(String filepath, String base64Content, Promise promise) {
140-
try {
153+
try (OutputStream outputStream = getOutputStream(filepath, true)) {
141154
byte[] bytes = Base64.decode(base64Content, Base64.DEFAULT);
142-
143-
OutputStream outputStream = getOutputStream(filepath, true);
144155
outputStream.write(bytes);
145-
outputStream.close();
146156

147157
promise.resolve(null);
148158
} catch (Exception ex) {
@@ -333,19 +343,10 @@ public void existsAssets(String filepath, Promise promise) {
333343
}
334344

335345
// Attempt to open file (win = exists)
336-
InputStream fileStream = null;
337-
try {
338-
fileStream = assetManager.open(filepath);
346+
try (InputStream fileStream = assetManager.open(filepath)) {
339347
promise.resolve(true);
340348
} catch (Exception ex) {
341349
promise.resolve(false); // don't throw an error, resolve false
342-
} finally {
343-
if (fileStream != null) {
344-
try {
345-
fileStream.close();
346-
} catch (Exception ignored) {
347-
}
348-
}
349350
}
350351
} catch (Exception ex) {
351352
ex.printStackTrace();
@@ -409,6 +410,7 @@ public void getFSInfo(Promise promise) {
409410

410411
@ReactMethod
411412
public void hash(String filepath, String algorithm, Promise promise) {
413+
FileInputStream inputStream = null;
412414
try {
413415
Map<String, String> algorithms = new HashMap<>();
414416

@@ -435,7 +437,7 @@ public void hash(String filepath, String algorithm, Promise promise) {
435437

436438
MessageDigest md = MessageDigest.getInstance(algorithms.get(algorithm));
437439

438-
FileInputStream inputStream = new FileInputStream(filepath);
440+
inputStream = new FileInputStream(filepath);
439441
byte[] buffer = new byte[1024 * 10]; // 10 KB Buffer
440442

441443
int read;
@@ -451,6 +453,8 @@ public void hash(String filepath, String algorithm, Promise promise) {
451453
} catch (Exception ex) {
452454
ex.printStackTrace();
453455
reject(promise, filepath, ex);
456+
} finally {
457+
closeIgnoringException(inputStream);
454458
}
455459
}
456460

@@ -539,8 +543,7 @@ public void read(
539543
double position,
540544
Promise promise
541545
) {
542-
try {
543-
InputStream inputStream = getInputStream(filepath);
546+
try (InputStream inputStream = getInputStream(filepath)) {
544547
byte[] buffer = new byte[(int)length];
545548
inputStream.skip((int)position);
546549
int bytesRead = inputStream.read(buffer, 0, (int)length);
@@ -624,8 +627,7 @@ public void readDirAssets(String directory, Promise promise) {
624627

625628
@ReactMethod
626629
public void readFile(String filepath, Promise promise) {
627-
try {
628-
InputStream inputStream = getInputStream(filepath);
630+
try (InputStream inputStream = getInputStream(filepath)) {
629631
byte[] inputData = getInputStreamBytes(inputStream);
630632
String base64Content = Base64.encodeToString(inputData, Base64.NO_WRAP);
631633

@@ -656,12 +658,7 @@ public void readFileAssets(String filepath, Promise promise) {
656658
ex.printStackTrace();
657659
reject(promise, filepath, ex);
658660
} finally {
659-
if (stream != null) {
660-
try {
661-
stream.close();
662-
} catch (IOException ignored) {
663-
}
664-
}
661+
closeIgnoringException(stream);
665662
}
666663
}
667664

@@ -684,12 +681,7 @@ public void readFileRes(String filename, Promise promise) {
684681
ex.printStackTrace();
685682
reject(promise, filename, ex);
686683
} finally {
687-
if (stream != null) {
688-
try {
689-
stream.close();
690-
} catch (IOException ignored) {
691-
}
692-
}
684+
closeIgnoringException(stream);
693685
}
694686
}
695687

@@ -794,7 +786,7 @@ public void touch(String filepath, ReadableMap options, Promise promise) {
794786
promise.resolve(file.setLastModified((long) mtime));
795787
} catch (Exception ex) {
796788
ex.printStackTrace();
797-
reject(promise, filepath, ex);
789+
reject(promise, filepath, ex);
798790
}
799791
}
800792

@@ -899,35 +891,35 @@ public void write(
899891
double position,
900892
Promise promise
901893
) {
894+
OutputStream outputStream = null;
895+
RandomAccessFile file = null;
902896
try {
903897
byte[] bytes = Base64.decode(base64Content, Base64.DEFAULT);
904898

905899
if (position < 0) {
906-
OutputStream outputStream = getOutputStream(filepath, true);
900+
outputStream = getOutputStream(filepath, true);
907901
outputStream.write(bytes);
908-
outputStream.close();
909902
} else {
910-
RandomAccessFile file = new RandomAccessFile(filepath, "rw");
903+
file = new RandomAccessFile(filepath, "rw");
911904
file.seek((long)position);
912905
file.write(bytes);
913-
file.close();
914906
}
915907

916908
promise.resolve(null);
917909
} catch (Exception ex) {
918910
ex.printStackTrace();
919911
reject(promise, filepath, ex);
912+
} finally {
913+
closeIgnoringException(outputStream);
914+
closeIgnoringException(file);
920915
}
921916
}
922917

923918
@ReactMethod
924919
public void writeFile(String filepath, String base64Content, ReadableMap options, Promise promise) {
925-
try {
920+
try (OutputStream outputStream = getOutputStream(filepath, false)) {
926921
byte[] bytes = Base64.decode(base64Content, Base64.DEFAULT);
927-
928-
OutputStream outputStream = getOutputStream(filepath, false);
929922
outputStream.write(bytes);
930-
outputStream.close();
931923

932924
promise.resolve(null);
933925
} catch (Exception ex) {
@@ -938,24 +930,27 @@ public void writeFile(String filepath, String base64Content, ReadableMap options
938930

939931
private class CopyFileTask extends AsyncTask<String, Void, Exception> {
940932
protected Exception doInBackground(String... paths) {
933+
InputStream in = null;
934+
OutputStream out = null;
941935
try {
942936
String filepath = paths[0];
943937
String destPath = paths[1];
944938

945-
InputStream in = getInputStream(filepath);
946-
OutputStream out = getOutputStream(destPath, false);
939+
in = getInputStream(filepath);
940+
out = getOutputStream(destPath, false);
947941

948942
byte[] buffer = new byte[1024];
949943
int length;
950944
while ((length = in.read(buffer)) > 0) {
951945
out.write(buffer, 0, length);
952946
Thread.yield();
953947
}
954-
in.close();
955-
out.close();
956948
return null;
957949
} catch (Exception ex) {
958950
return ex;
951+
} finally {
952+
closeIgnoringException(in);
953+
closeIgnoringException(out);
959954
}
960955
}
961956
}
@@ -984,18 +979,8 @@ private void copyInputStream(InputStream in, String source, String destination,
984979
} catch (Exception ex) {
985980
reject(promise, source, new Exception(String.format("Failed to copy '%s' to %s (%s)", source, destination, ex.getLocalizedMessage())));
986981
} finally {
987-
if (in != null) {
988-
try {
989-
in.close();
990-
} catch (IOException ignored) {
991-
}
992-
}
993-
if (out != null) {
994-
try {
995-
out.close();
996-
} catch (IOException ignored) {
997-
}
998-
}
982+
closeIgnoringException(in);
983+
closeIgnoringException(out);
999984
}
1000985
}
1001986

@@ -1038,20 +1023,14 @@ private InputStream getInputStream(String filepath) throws IORejectionException
10381023

10391024
private static byte[] getInputStreamBytes(InputStream inputStream) throws IOException {
10401025
byte[] bytesResult;
1041-
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
10421026
int bufferSize = 1024;
10431027
byte[] buffer = new byte[bufferSize];
1044-
try {
1028+
try (ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream()) {
10451029
int len;
10461030
while ((len = inputStream.read(buffer)) != -1) {
10471031
byteBuffer.write(buffer, 0, len);
10481032
}
10491033
bytesResult = byteBuffer.toByteArray();
1050-
} finally {
1051-
try {
1052-
byteBuffer.close();
1053-
} catch (IOException ignored) {
1054-
}
10551034
}
10561035
return bytesResult;
10571036
}
@@ -1127,57 +1106,3 @@ private void sendEvent(ReactContext reactContext, String eventName, WritableMap
11271106
emitter.emit(eventName, params);
11281107
}
11291108
}
1130-
1131-
/**
1132-
* TODO: This is the original module file
1133-
*
1134-
-
1135-
-
1136-
-
1137-
-
1138-
-
1139-
-
1140-
-
1141-
-
1142-
-
1143-
-
1144-
-
1145-
-
1146-
-
1147-
-import com.facebook.react.bridge.Promise;
1148-
-import com.facebook.react.bridge.ReactApplicationContext;
1149-
-
1150-
-import com.facebook.react.bridge.ReactContextBaseJavaModule;
1151-
-import com.facebook.react.bridge.ReactMethod;
1152-
-
1153-
1154-
-
1155-
-
1156-
-import com.facebook.react.module.annotations.ReactModule;
1157-
-
1158-
-
1159-
-
1160-
-
1161-
-
1162-
-import java.util.HashMap;
1163-
-import java.util.Map;
1164-
-
1165-
- private static final String RNFSDocumentDirectoryPath = "RNFSDocumentDirectoryPath";
1166-
- private static final String RNFSExternalDirectoryPath = "RNFSExternalDirectoryPath";
1167-
- private static final String RNFSExternalStorageDirectoryPath = "RNFSExternalStorageDirectoryPath";
1168-
- private static final String RNFSPicturesDirectoryPath = "RNFSPicturesDirectoryPath";
1169-
- private static final String RNFSDownloadDirectoryPath = "RNFSDownloadDirectoryPath";
1170-
- private static final String RNFSTemporaryDirectoryPath = "RNFSTemporaryDirectoryPath";
1171-
- private static final String RNFSCachesDirectoryPath = "RNFSCachesDirectoryPath";
1172-
- private static final String RNFSExternalCachesDirectoryPath = "RNFSExternalCachesDirectoryPath";
1173-
- private static final String RNFSDocumentDirectory = "RNFSDocumentDirectory";
1174-
-
1175-
- private static final String RNFSFileTypeRegular = "RNFSFileTypeRegular";
1176-
- private static final String RNFSFileTypeDirectory = "RNFSFileTypeDirectory";
1177-
-
1178-
- private SparseArray<Downloader> downloaders = new SparseArray<>();
1179-
- private SparseArray<Uploader> uploaders = new SparseArray<>();
1180-
-
1181-
- private ReactApplicationContext reactContext;
1182-
-
1183-
*/

0 commit comments

Comments
 (0)