react-native-blob-util 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -0
- package/android/src/main/AndroidManifest.xml +0 -3
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +11 -12
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilBody.java +30 -6
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +2 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +94 -3
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFileTransformer.java +10 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java +123 -87
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +99 -1
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilUtils.java +5 -17
- package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +4 -0
- package/class/ReactNativeBlobUtilBlobResponse.js +1 -1
- package/fs.js +42 -3
- package/index.d.ts +30 -1
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.m +4 -3
- package/ios/ReactNativeBlobUtil.xcodeproj/project.pbxproj +6 -2
- package/ios/ReactNativeBlobUtilConst.h +1 -0
- package/ios/ReactNativeBlobUtilConst.m +1 -0
- package/ios/ReactNativeBlobUtilFS.h +2 -1
- package/ios/ReactNativeBlobUtilFS.m +30 -2
- package/ios/ReactNativeBlobUtilFileTransformer.h +24 -0
- package/ios/ReactNativeBlobUtilFileTransformer.m +21 -0
- package/ios/ReactNativeBlobUtilReqBuilder.m +3 -4
- package/ios/ReactNativeBlobUtilRequest.m +35 -7
- package/mediacollection.js +6 -1
- package/package.json +1 -1
- package/polyfill/Fetch.js +4 -2
- package/types.js +1 -0
- package/ios/IOS7Polyfill.h +0 -27
package/README.md
CHANGED
|
@@ -303,6 +303,26 @@ ReactNativeBlobUtil
|
|
|
303
303
|
|
|
304
304
|
**These files won't be removed automatically, please refer to [Cache File Management](#user-content-cache-file-management)**
|
|
305
305
|
|
|
306
|
+
**Use File Transformer**
|
|
307
|
+
|
|
308
|
+
If you need to perform any processing on the bytes prior to it being written into storage (e.g. if you want it to be encrypted) then you can use `transform` option. NOTE: you will need to set a transformer on the libray (see [Setting a File Transformer](#Setting-A-File-Transformer))
|
|
309
|
+
|
|
310
|
+
```js
|
|
311
|
+
ReactNativeBlobUtil
|
|
312
|
+
.config({
|
|
313
|
+
// response data will be saved to this path if it has access right.
|
|
314
|
+
path: dirs.DocumentDir + '/path-to-file.anything',
|
|
315
|
+
transform: true
|
|
316
|
+
})
|
|
317
|
+
.fetch('GET', 'http://www.example.com/file/example.zip', {
|
|
318
|
+
//some headers ..
|
|
319
|
+
})
|
|
320
|
+
.then((res) => {
|
|
321
|
+
// the path should be dirs.DocumentDir + 'path-to-file.anything'
|
|
322
|
+
console.log('The file saved to ', res.path())
|
|
323
|
+
})
|
|
324
|
+
```
|
|
325
|
+
|
|
306
326
|
#### Upload example : Dropbox [files-upload](https://www.dropbox.com/developers/documentation/http/documentation#files-upload) API
|
|
307
327
|
|
|
308
328
|
`react-native-blob-util` will convert the base64 string in `body` to binary format using native API, this process is done in a separated thread so that it won't block your GUI.
|
|
@@ -676,6 +696,14 @@ await ReactNativeBlobUtil.MediaCollection.writeToMediafile('content://....', //
|
|
|
676
696
|
);
|
|
677
697
|
````
|
|
678
698
|
|
|
699
|
+
Copies and tranforms data from a file in the apps storage to an existing entry of the Media Store. NOTE: you must set a transformer on the file in order for the transformation to happen (see [Setting a File Transformer](#Setting-A-File-Transformer)).
|
|
700
|
+
|
|
701
|
+
````js
|
|
702
|
+
await ReactNativeBlobUtil.MediaCollection.writeToMediafileWithTransform('content://....', // content uri of the entry in the media storage
|
|
703
|
+
localpath // path to the file that should be copied
|
|
704
|
+
);
|
|
705
|
+
````
|
|
706
|
+
|
|
679
707
|
#### copyToInternal
|
|
680
708
|
Copies an entry form the media storage to the apps internal storage.
|
|
681
709
|
````js
|
|
@@ -697,8 +725,10 @@ File Access APIs
|
|
|
697
725
|
- [dirs](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#dirs)
|
|
698
726
|
- [createFile](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#createfilepath-data-encodingpromise)
|
|
699
727
|
- [writeFile (0.6.0)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#writefilepathstring-contentstring--array-encodingstring-appendbooleanpromise)
|
|
728
|
+
- writeFileWithTransform
|
|
700
729
|
- [appendFile (0.6.0) ](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#appendfilepathstring-contentstring--arraynumber-encodingstring-promisenumber)
|
|
701
730
|
- [readFile (0.6.0)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#readfilepath-encodingpromise)
|
|
731
|
+
- readFileWithTransform
|
|
702
732
|
- [readStream](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#readstreampath-encoding-buffersize-interval-promisernfbreadstream)
|
|
703
733
|
- [hash (0.10.9)](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#hashpath-algorithm-promise)
|
|
704
734
|
- [writeStream](https://github.com/RonRadtke/react-native-blob-util/wiki/File-System-Access-API#writestreampathstring-encodingstringpromise)
|
|
@@ -878,6 +908,30 @@ ReactNativeBlobUtil.fetch('POST', 'http://example.com/upload', {'Transfer-Encodi
|
|
|
878
908
|
### Self-Signed SSL Server
|
|
879
909
|
|
|
880
910
|
By default, react-native-blob-util does NOT allow connection to unknown certification provider since it's dangerous. To connect a server with self-signed certification, you need to add `trusty` to `config` explicitly. This function is available for version >= `0.5.3`
|
|
911
|
+
In addition since ``0.16.0`` you'll have to define your own trust manager for android.
|
|
912
|
+
````java
|
|
913
|
+
public class MainApplication extends Application implements ReactApplication {
|
|
914
|
+
...
|
|
915
|
+
@Override
|
|
916
|
+
public void onCreate() {
|
|
917
|
+
...
|
|
918
|
+
ReactNativeBlobUtilUtils.sharedTrustManager = final X509TrustManager x509TrustManager = new X509TrustManager() {
|
|
919
|
+
@Override
|
|
920
|
+
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
@Override
|
|
924
|
+
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
@Override
|
|
928
|
+
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
|
929
|
+
return new java.security.cert.X509Certificate[]{};
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
...
|
|
933
|
+
}
|
|
934
|
+
````
|
|
881
935
|
|
|
882
936
|
```js
|
|
883
937
|
ReactNativeBlobUtil.config({
|
|
@@ -903,6 +957,10 @@ ReactNativeBlobUtil.config({
|
|
|
903
957
|
})
|
|
904
958
|
```
|
|
905
959
|
|
|
960
|
+
### Transform Files
|
|
961
|
+
|
|
962
|
+
Sometimes you may need the files to be transformed after reading from storage or before writing into storage (eg encryption/decyrption). In order to perform the transformations, use `readFileWithTransform` and `writeFileWithTransform`. NOTE: you must set a transformer on the file in order for the transformation to happen (see [Setting a File Transformer](#Setting-A-File-Transformer)).
|
|
963
|
+
|
|
906
964
|
## Web API Polyfills
|
|
907
965
|
|
|
908
966
|
After `0.8.0` we've made some [Web API polyfills](https://github.com/RonRadtke/react-native-blob-util/wiki/Web-API-Polyfills-(experimental)) that makes some browser-based library available in RN.
|
|
@@ -910,6 +968,48 @@ After `0.8.0` we've made some [Web API polyfills](https://github.com/RonRadtke/r
|
|
|
910
968
|
- Blob
|
|
911
969
|
- XMLHttpRequest (Use our implementation if you're going to use it with Blob)
|
|
912
970
|
|
|
971
|
+
|
|
972
|
+
## Setting A File Transformer
|
|
973
|
+
|
|
974
|
+
Setting a file transformer will allow you to specify how data should be transformed whenever the library is writing into storage or reading from storage. A use case for this is if you want the files handled by this library to be encrypted.
|
|
975
|
+
|
|
976
|
+
If you want to use a file transformer, you must implement an interface defined in:
|
|
977
|
+
|
|
978
|
+
[ReactNativeBlobUtilFileTransformer.h (iOS)](/ios/ReactNativeBlobUtilFileTransformer.h)
|
|
979
|
+
|
|
980
|
+
[ReactNativeBlobUtilFileTransformer.java (Android)](/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFileTransformer.java)
|
|
981
|
+
|
|
982
|
+
Then you set the File Transformer during app startup
|
|
983
|
+
|
|
984
|
+
Android:
|
|
985
|
+
```java
|
|
986
|
+
public class MainApplication extends Application implements ReactApplication {
|
|
987
|
+
...
|
|
988
|
+
@Override
|
|
989
|
+
public void onCreate() {
|
|
990
|
+
...
|
|
991
|
+
ReactNativeBlobUtilFileTransformer.sharedFileTransformer = new MyCustomEncryptor();
|
|
992
|
+
...
|
|
993
|
+
}
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
iOS:
|
|
997
|
+
```m
|
|
998
|
+
@implementation AppDelegate
|
|
999
|
+
...
|
|
1000
|
+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
|
1001
|
+
{
|
|
1002
|
+
...
|
|
1003
|
+
[ReactNativeBlobUtilFileTransformer setFileTransformer: MyCustomEncryptor.new];
|
|
1004
|
+
...
|
|
1005
|
+
}
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
Here are the places where the transformer would apply
|
|
1009
|
+
- Reading a file from the file system
|
|
1010
|
+
- Writing a file into the file system
|
|
1011
|
+
- Http response is downloaded to storage directly
|
|
1012
|
+
|
|
913
1013
|
## Performance Tips
|
|
914
1014
|
|
|
915
1015
|
**Read Stream and Progress Event Overhead**
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
2
|
package="com.ReactNativeBlobUtil">
|
|
3
3
|
|
|
4
|
-
<!-- Required to access Google Play Licensing -->
|
|
5
|
-
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
|
|
6
|
-
|
|
7
4
|
<!-- Required to download files from Google Play -->
|
|
8
5
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
9
6
|
|
|
@@ -233,11 +233,11 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
@ReactMethod
|
|
236
|
-
public void readFile(final String path, final String encoding, final Promise promise) {
|
|
236
|
+
public void readFile(final String path, final String encoding, final boolean transformFile, final Promise promise) {
|
|
237
237
|
threadPool.execute(new Runnable() {
|
|
238
238
|
@Override
|
|
239
239
|
public void run() {
|
|
240
|
-
ReactNativeBlobUtilFS.readFile(path, encoding, promise);
|
|
240
|
+
ReactNativeBlobUtilFS.readFile(path, encoding, transformFile, promise);
|
|
241
241
|
}
|
|
242
242
|
});
|
|
243
243
|
}
|
|
@@ -253,11 +253,11 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
@ReactMethod
|
|
256
|
-
public void writeFile(final String path, final String encoding, final String data, final boolean append, final Promise promise) {
|
|
256
|
+
public void writeFile(final String path, final String encoding, final String data, final boolean transformFile, final boolean append, final Promise promise) {
|
|
257
257
|
threadPool.execute(new Runnable() {
|
|
258
258
|
@Override
|
|
259
259
|
public void run() {
|
|
260
|
-
ReactNativeBlobUtilFS.writeFile(path, encoding, data, append, promise);
|
|
260
|
+
ReactNativeBlobUtilFS.writeFile(path, encoding, data, transformFile, append, promise);
|
|
261
261
|
}
|
|
262
262
|
});
|
|
263
263
|
}
|
|
@@ -432,29 +432,29 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
432
432
|
if (mt == null) promise.reject("ReactNativeBlobUtil.createMediaFile", "invalid mediatype");
|
|
433
433
|
|
|
434
434
|
FileDescription file = new FileDescription(filedata.getString("name"), filedata.getString("mimeType"), filedata.getString("parentFolder"));
|
|
435
|
-
Uri res = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt));
|
|
435
|
+
Uri res = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt), this.getReactApplicationContext());
|
|
436
436
|
if (res != null) promise.resolve(res.toString());
|
|
437
437
|
else promise.reject("ReactNativeBlobUtil.createMediaFile", "File could not be created");
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
-
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
441
440
|
@ReactMethod
|
|
442
|
-
public void writeToMediaFile(String fileUri, String path, Promise promise) {
|
|
443
|
-
boolean res = ReactNativeBlobUtilMediaCollection.writeToMediaFile(Uri.parse(fileUri), path, promise);
|
|
441
|
+
public void writeToMediaFile(String fileUri, String path, boolean transformFile, Promise promise) {
|
|
442
|
+
boolean res = ReactNativeBlobUtilMediaCollection.writeToMediaFile(Uri.parse(fileUri), path, transformFile, promise);
|
|
444
443
|
if(res) promise.resolve("Success");
|
|
445
444
|
}
|
|
446
445
|
|
|
446
|
+
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
447
447
|
@ReactMethod
|
|
448
448
|
public void copyToInternal(String contentUri, String destpath, Promise promise) {
|
|
449
449
|
ReactNativeBlobUtilMediaCollection.copyToInternal(Uri.parse(contentUri), destpath, promise);
|
|
450
450
|
}
|
|
451
451
|
|
|
452
|
+
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
452
453
|
@ReactMethod
|
|
453
454
|
public void getBlob(String contentUri, String encoding, Promise promise) {
|
|
454
455
|
ReactNativeBlobUtilMediaCollection.getBlob(Uri.parse(contentUri), encoding, promise);
|
|
455
456
|
}
|
|
456
457
|
|
|
457
|
-
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
458
458
|
@ReactMethod
|
|
459
459
|
public void copyToMediaStore(ReadableMap filedata, String mt, String path, Promise promise) {
|
|
460
460
|
if (!(filedata.hasKey("name") && filedata.hasKey("parentFolder") && filedata.hasKey("mimeType"))) {
|
|
@@ -471,15 +471,14 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
FileDescription file = new FileDescription(filedata.getString("name"), filedata.getString("mimeType"), filedata.getString("parentFolder"));
|
|
474
|
-
Uri fileuri = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt));
|
|
474
|
+
Uri fileuri = ReactNativeBlobUtilMediaCollection.createNewMediaFile(file, ReactNativeBlobUtilMediaCollection.MediaType.valueOf(mt), this.getReactApplicationContext());
|
|
475
475
|
|
|
476
476
|
if (fileuri == null) {
|
|
477
477
|
promise.reject("ReactNativeBlobUtil.createMediaFile", "File could not be created");
|
|
478
478
|
return;
|
|
479
479
|
}
|
|
480
480
|
|
|
481
|
-
boolean res = ReactNativeBlobUtilMediaCollection.writeToMediaFile(fileuri, path, promise);
|
|
482
|
-
|
|
481
|
+
boolean res = ReactNativeBlobUtilMediaCollection.writeToMediaFile(fileuri, path, false, promise);
|
|
483
482
|
if(res) promise.resolve(fileuri.toString());
|
|
484
483
|
}
|
|
485
484
|
|
|
@@ -26,7 +26,6 @@ import okio.BufferedSink;
|
|
|
26
26
|
|
|
27
27
|
class ReactNativeBlobUtilBody extends RequestBody {
|
|
28
28
|
|
|
29
|
-
private InputStream requestStream;
|
|
30
29
|
private long contentLength = 0;
|
|
31
30
|
private ReadableArray form;
|
|
32
31
|
private String mTaskId;
|
|
@@ -71,12 +70,10 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
71
70
|
try {
|
|
72
71
|
switch (requestType) {
|
|
73
72
|
case SingleFile:
|
|
74
|
-
|
|
75
|
-
contentLength = requestStream.available();
|
|
73
|
+
contentLength = getRequestStream().available();
|
|
76
74
|
break;
|
|
77
75
|
case AsIs:
|
|
78
76
|
contentLength = this.rawBody.getBytes().length;
|
|
79
|
-
requestStream = new ByteArrayInputStream(this.rawBody.getBytes());
|
|
80
77
|
break;
|
|
81
78
|
case Others:
|
|
82
79
|
break;
|
|
@@ -98,7 +95,6 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
98
95
|
this.form = body;
|
|
99
96
|
try {
|
|
100
97
|
bodyCache = createMultipartBodyCache();
|
|
101
|
-
requestStream = new FileInputStream(bodyCache);
|
|
102
98
|
contentLength = bodyCache.length();
|
|
103
99
|
} catch (Exception ex) {
|
|
104
100
|
ex.printStackTrace();
|
|
@@ -107,6 +103,34 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
107
103
|
return this;
|
|
108
104
|
}
|
|
109
105
|
|
|
106
|
+
// This organizes the input stream initialization logic into a method. This allows:
|
|
107
|
+
// 1) Initialization to be deferred until it's needed (when we are ready to pipe it into the BufferedSink)
|
|
108
|
+
// 2) The stream to be initialized and used as many times as necessary. When okhttp runs into
|
|
109
|
+
// a connection error, it will retry the request which will require a new stream to write into
|
|
110
|
+
// the sink once again.
|
|
111
|
+
InputStream getInputStreamForRequestBody() {
|
|
112
|
+
try {
|
|
113
|
+
if (this.form != null) {
|
|
114
|
+
return new FileInputStream(bodyCache);
|
|
115
|
+
} else {
|
|
116
|
+
switch (requestType) {
|
|
117
|
+
case SingleFile:
|
|
118
|
+
return getRequestStream();
|
|
119
|
+
case AsIs:
|
|
120
|
+
return new ByteArrayInputStream(this.rawBody.getBytes());
|
|
121
|
+
case Others:
|
|
122
|
+
ReactNativeBlobUtilUtils.emitWarningEvent("ReactNativeBlobUtil could not create input stream for request type others");
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} catch (Exception ex){
|
|
127
|
+
ex.printStackTrace();
|
|
128
|
+
ReactNativeBlobUtilUtils.emitWarningEvent("ReactNativeBlobUtil failed to create input stream for request:" + ex.getLocalizedMessage());
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
110
134
|
@Override
|
|
111
135
|
public long contentLength() {
|
|
112
136
|
return chunkedEncoding ? -1 : contentLength;
|
|
@@ -120,7 +144,7 @@ class ReactNativeBlobUtilBody extends RequestBody {
|
|
|
120
144
|
@Override
|
|
121
145
|
public void writeTo(@NonNull BufferedSink sink) {
|
|
122
146
|
try {
|
|
123
|
-
pipeStreamToSink(
|
|
147
|
+
pipeStreamToSink(getInputStreamForRequestBody(), sink);
|
|
124
148
|
} catch (Exception ex) {
|
|
125
149
|
ReactNativeBlobUtilUtils.emitWarningEvent(ex.getLocalizedMessage());
|
|
126
150
|
ex.printStackTrace();
|
|
@@ -8,6 +8,7 @@ import java.util.Locale;
|
|
|
8
8
|
class ReactNativeBlobUtilConfig {
|
|
9
9
|
|
|
10
10
|
public Boolean fileCache;
|
|
11
|
+
public Boolean transformFile;
|
|
11
12
|
public String path;
|
|
12
13
|
public String appendExt;
|
|
13
14
|
public ReadableMap addAndroidDownloads;
|
|
@@ -26,6 +27,7 @@ class ReactNativeBlobUtilConfig {
|
|
|
26
27
|
if (options == null)
|
|
27
28
|
return;
|
|
28
29
|
this.fileCache = options.hasKey("fileCache") && options.getBoolean("fileCache");
|
|
30
|
+
this.transformFile = options.hasKey("transformFile") ? options.getBoolean("transformFile") : false;
|
|
29
31
|
this.path = options.hasKey("path") ? options.getString("path") : null;
|
|
30
32
|
this.appendExt = options.hasKey("appendExt") ? options.getString("appendExt") : "";
|
|
31
33
|
this.trusty = options.hasKey("trusty") && options.getBoolean("trusty");
|
|
@@ -44,6 +44,76 @@ class ReactNativeBlobUtilFS {
|
|
|
44
44
|
this.emitter = ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Write string with encoding to file (used for mediastore)
|
|
49
|
+
*
|
|
50
|
+
* @param path Destination file path.
|
|
51
|
+
* @param encoding Encoding of the string.
|
|
52
|
+
* @param data Array passed from JS context.
|
|
53
|
+
*/
|
|
54
|
+
static boolean writeFile(String path, String encoding, String data, final boolean append) {
|
|
55
|
+
try {
|
|
56
|
+
int written;
|
|
57
|
+
path = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
58
|
+
File f = new File(path);
|
|
59
|
+
File dir = f.getParentFile();
|
|
60
|
+
if (!f.exists()) {
|
|
61
|
+
if (dir != null && !dir.exists()) {
|
|
62
|
+
if (!dir.mkdirs() && !dir.exists()) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (!f.createNewFile()) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// write data from a file
|
|
72
|
+
if (encoding.equalsIgnoreCase(ReactNativeBlobUtilConst.DATA_ENCODE_URI)) {
|
|
73
|
+
String normalizedData = ReactNativeBlobUtilUtils.normalizePath(data);
|
|
74
|
+
File src = new File(normalizedData);
|
|
75
|
+
if (!src.exists()) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
byte[] buffer = new byte[10240];
|
|
79
|
+
int read;
|
|
80
|
+
written = 0;
|
|
81
|
+
FileInputStream fin = null;
|
|
82
|
+
FileOutputStream fout = null;
|
|
83
|
+
try {
|
|
84
|
+
fin = new FileInputStream(src);
|
|
85
|
+
fout = new FileOutputStream(f, append);
|
|
86
|
+
while ((read = fin.read(buffer)) > 0) {
|
|
87
|
+
fout.write(buffer, 0, read);
|
|
88
|
+
written += read;
|
|
89
|
+
}
|
|
90
|
+
} finally {
|
|
91
|
+
if (fin != null) {
|
|
92
|
+
fin.close();
|
|
93
|
+
}
|
|
94
|
+
if (fout != null) {
|
|
95
|
+
fout.close();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
byte[] bytes = ReactNativeBlobUtilUtils.stringToBytes(data, encoding);
|
|
100
|
+
FileOutputStream fout = new FileOutputStream(f, append);
|
|
101
|
+
try {
|
|
102
|
+
fout.write(bytes);
|
|
103
|
+
written = bytes.length;
|
|
104
|
+
} finally {
|
|
105
|
+
fout.close();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
} catch (FileNotFoundException e) {
|
|
110
|
+
// According to https://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html
|
|
111
|
+
return false;
|
|
112
|
+
} catch (Exception e) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
47
117
|
/**
|
|
48
118
|
* Write string with encoding to file
|
|
49
119
|
*
|
|
@@ -52,12 +122,11 @@ class ReactNativeBlobUtilFS {
|
|
|
52
122
|
* @param data Array passed from JS context.
|
|
53
123
|
* @param promise RCT Promise
|
|
54
124
|
*/
|
|
55
|
-
static void writeFile(String path, String encoding, String data, final boolean append, final Promise promise) {
|
|
125
|
+
static void writeFile(String path, String encoding, String data, final boolean transformFile, final boolean append, final Promise promise) {
|
|
56
126
|
try {
|
|
57
127
|
int written;
|
|
58
128
|
File f = new File(path);
|
|
59
129
|
File dir = f.getParentFile();
|
|
60
|
-
|
|
61
130
|
if (!f.exists()) {
|
|
62
131
|
if (dir != null && !dir.exists()) {
|
|
63
132
|
if (!dir.mkdirs() && !dir.exists()) {
|
|
@@ -101,6 +170,12 @@ class ReactNativeBlobUtilFS {
|
|
|
101
170
|
}
|
|
102
171
|
} else {
|
|
103
172
|
byte[] bytes = ReactNativeBlobUtilUtils.stringToBytes(data, encoding);
|
|
173
|
+
if (transformFile) {
|
|
174
|
+
if (ReactNativeBlobUtilFileTransformer.sharedFileTransformer == null) {
|
|
175
|
+
throw new IllegalStateException("Write file with transform was specified but the shared file transformer is not set");
|
|
176
|
+
}
|
|
177
|
+
bytes = ReactNativeBlobUtilFileTransformer.sharedFileTransformer.onWriteFile(bytes);
|
|
178
|
+
}
|
|
104
179
|
FileOutputStream fout = new FileOutputStream(f, append);
|
|
105
180
|
try {
|
|
106
181
|
fout.write(bytes);
|
|
@@ -169,7 +244,7 @@ class ReactNativeBlobUtilFS {
|
|
|
169
244
|
* @param encoding Encoding of read stream.
|
|
170
245
|
* @param promise JS promise
|
|
171
246
|
*/
|
|
172
|
-
static void readFile(String path, String encoding, final Promise promise) {
|
|
247
|
+
static void readFile(String path, String encoding, final boolean transformFile, final Promise promise) {
|
|
173
248
|
String resolved = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
174
249
|
if (resolved != null)
|
|
175
250
|
path = resolved;
|
|
@@ -212,6 +287,13 @@ class ReactNativeBlobUtilFS {
|
|
|
212
287
|
return;
|
|
213
288
|
}
|
|
214
289
|
|
|
290
|
+
if (transformFile) {
|
|
291
|
+
if (ReactNativeBlobUtilFileTransformer.sharedFileTransformer == null) {
|
|
292
|
+
throw new IllegalStateException("Read file with transform was specified but the shared file transformer is not set");
|
|
293
|
+
}
|
|
294
|
+
bytes = ReactNativeBlobUtilFileTransformer.sharedFileTransformer.onReadFile(bytes);
|
|
295
|
+
}
|
|
296
|
+
|
|
215
297
|
switch (encoding.toLowerCase(Locale.ROOT)) {
|
|
216
298
|
case "base64":
|
|
217
299
|
promise.resolve(Base64.encodeToString(bytes, Base64.NO_WRAP));
|
|
@@ -373,6 +455,7 @@ class ReactNativeBlobUtilFS {
|
|
|
373
455
|
* @param promise JS promise
|
|
374
456
|
*/
|
|
375
457
|
static void mkdir(String path, Promise promise) {
|
|
458
|
+
path = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
376
459
|
File dest = new File(path);
|
|
377
460
|
if (dest.exists()) {
|
|
378
461
|
promise.reject("EEXIST", (dest.isDirectory() ? "Folder" : "File") + " '" + path + "' already exists");
|
|
@@ -400,6 +483,7 @@ class ReactNativeBlobUtilFS {
|
|
|
400
483
|
*/
|
|
401
484
|
static void cp(String path, String dest, Callback callback) {
|
|
402
485
|
path = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
486
|
+
dest = ReactNativeBlobUtilUtils.normalizePath(dest);
|
|
403
487
|
InputStream in = null;
|
|
404
488
|
OutputStream out = null;
|
|
405
489
|
String message = "";
|
|
@@ -456,6 +540,8 @@ class ReactNativeBlobUtilFS {
|
|
|
456
540
|
* @param callback JS context callback
|
|
457
541
|
*/
|
|
458
542
|
static void mv(String path, String dest, Callback callback) {
|
|
543
|
+
path = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
544
|
+
dest = ReactNativeBlobUtilUtils.normalizePath(dest);
|
|
459
545
|
File src = new File(path);
|
|
460
546
|
if (!src.exists()) {
|
|
461
547
|
callback.invoke("Source file at path `" + path + "` does not exist");
|
|
@@ -559,6 +645,7 @@ class ReactNativeBlobUtilFS {
|
|
|
559
645
|
static void slice(String path, String dest, int start, int end, String encode, Promise promise) {
|
|
560
646
|
try {
|
|
561
647
|
path = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
648
|
+
dest = ReactNativeBlobUtilUtils.normalizePath(dest);
|
|
562
649
|
File source = new File(path);
|
|
563
650
|
if (source.isDirectory()) {
|
|
564
651
|
promise.reject("EISDIR", "Expecting a file but '" + path + "' is a directory");
|
|
@@ -722,6 +809,8 @@ class ReactNativeBlobUtilFS {
|
|
|
722
809
|
promise.reject("EINVAL", "Invalid algorithm '" + algorithm + "', must be one of md5, sha1, sha224, sha256, sha384, sha512");
|
|
723
810
|
return;
|
|
724
811
|
}
|
|
812
|
+
|
|
813
|
+
path = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
725
814
|
|
|
726
815
|
File file = new File(path);
|
|
727
816
|
|
|
@@ -769,6 +858,7 @@ class ReactNativeBlobUtilFS {
|
|
|
769
858
|
*/
|
|
770
859
|
static void createFile(String path, String data, String encoding, Promise promise) {
|
|
771
860
|
try {
|
|
861
|
+
path = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
772
862
|
File dest = new File(path);
|
|
773
863
|
boolean created = dest.createNewFile();
|
|
774
864
|
if (encoding.equals(ReactNativeBlobUtilConst.DATA_ENCODE_URI)) {
|
|
@@ -811,6 +901,7 @@ class ReactNativeBlobUtilFS {
|
|
|
811
901
|
*/
|
|
812
902
|
static void createFileASCII(String path, ReadableArray data, Promise promise) {
|
|
813
903
|
try {
|
|
904
|
+
path = ReactNativeBlobUtilUtils.normalizePath(path);
|
|
814
905
|
File dest = new File(path);
|
|
815
906
|
boolean created = dest.createNewFile();
|
|
816
907
|
if (!created) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package com.ReactNativeBlobUtil;
|
|
2
|
+
|
|
3
|
+
public class ReactNativeBlobUtilFileTransformer {
|
|
4
|
+
public interface FileTransformer {
|
|
5
|
+
public byte[] onWriteFile(byte[] data);
|
|
6
|
+
public byte[] onReadFile(byte[] data);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
public static ReactNativeBlobUtilFileTransformer.FileTransformer sharedFileTransformer;
|
|
10
|
+
}
|