Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit 94c30a7

Browse files
committed
#124 Add Android and IOS fs.open implementations
1 parent 637a53b commit 94c30a7

File tree

13 files changed

+576
-106
lines changed

13 files changed

+576
-106
lines changed

android/src/main/java/com/RNFetchBlob/RNFetchBlob.java

Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44
import android.app.DownloadManager;
55
import android.content.Intent;
66
import android.net.Uri;
7-
import android.support.annotation.Nullable;
87

9-
import com.RNFetchBlob.Utils.EncodingResolver;
10-
import com.RNFetchBlob.Utils.RNFBCookieJar;
8+
import com.RNFetchBlob.Utils.DataConverter;
119
import com.facebook.react.bridge.ActivityEventListener;
1210
import com.facebook.react.bridge.Callback;
1311
import com.facebook.react.bridge.LifecycleEventListener;
@@ -18,20 +16,24 @@
1816
import com.facebook.react.bridge.ReadableArray;
1917
import com.facebook.react.bridge.ReadableMap;
2018
import com.facebook.react.bridge.WritableMap;
21-
import com.facebook.react.modules.network.ForwardingCookieHandler;
2219
import com.facebook.react.modules.network.CookieJarContainer;
20+
import com.facebook.react.modules.network.ForwardingCookieHandler;
2321
import com.facebook.react.modules.network.OkHttpClientProvider;
24-
import okhttp3.OkHttpClient;
25-
import okhttp3.JavaNetCookieJar;
2622

2723
import java.util.HashMap;
2824
import java.util.Map;
2925
import java.util.concurrent.LinkedBlockingQueue;
3026
import java.util.concurrent.ThreadPoolExecutor;
3127
import java.util.concurrent.TimeUnit;
3228

29+
import okhttp3.JavaNetCookieJar;
30+
import okhttp3.OkHttpClient;
31+
3332
import static android.app.Activity.RESULT_OK;
3433
import static com.RNFetchBlob.RNFetchBlobConst.GET_CONTENT_INTENT;
34+
import static com.RNFetchBlob.RNFetchBlobConst.RNFB_RESPONSE_ASCII;
35+
import static com.RNFetchBlob.RNFetchBlobConst.RNFB_RESPONSE_BASE64;
36+
import static com.RNFetchBlob.RNFetchBlobConst.RNFB_RESPONSE_UTF8;
3537

3638
public class RNFetchBlob extends ReactContextBaseJavaModule {
3739

@@ -315,39 +317,6 @@ public void run() {
315317
});
316318
}
317319

318-
@ReactMethod
319-
public void readChunk(final String path, final String encoding, final int offset, final int length, final Promise promise) {
320-
fsThreadPool.execute(new Runnable() {
321-
@Override
322-
public void run() {
323-
try {
324-
Object result = RNFetchBlobFS.readChunk(path, encoding, offset, length);
325-
EncodingResolver.resolve(promise, encoding, result);
326-
} catch (Exception e) {
327-
e.printStackTrace();
328-
promise.reject(e.getMessage(), e.getMessage()) ;
329-
}
330-
}
331-
});
332-
333-
}
334-
335-
@ReactMethod
336-
public void writeChunk(final String path, final String encoding, final String data, final int offset, final int length, final Promise promise) {
337-
fsThreadPool.execute(new Runnable() {
338-
@Override
339-
public void run() {
340-
try {
341-
RNFetchBlobFS.writeChunk(path, encoding, data, offset);
342-
promise.resolve(null);
343-
} catch (Exception e) {
344-
e.printStackTrace();
345-
promise.reject(e.getMessage(), e.getMessage()) ;
346-
}
347-
}
348-
});
349-
}
350-
351320

352321
@ReactMethod
353322
public void enableUploadProgressReport(String taskId, int interval, int count) {
@@ -366,27 +335,99 @@ public void fetchBlobForm(ReadableMap options, String taskId, String method, Str
366335
}
367336

368337
@ReactMethod
369-
public void read(final String path, final String encoding, final int offset, final int length, final @Nullable String dest, final Promise promise) {
338+
public void openFileHandle(final String path, final int mode, final Promise promise) {
370339
fsThreadPool.execute(new Runnable() {
371340
@Override
372341
public void run() {
373-
RNFetchBlobFS fs = new RNFetchBlobFS(RCTContext);
374-
fs.read(path, encoding, offset, length, dest, promise);
342+
RNFetchBlobOpenFile.Mode accessMode = RNFetchBlobOpenFile.Mode.READ;
343+
if(mode == 1)
344+
accessMode = RNFetchBlobOpenFile.Mode.READ;
345+
else if (mode == 2)
346+
accessMode = RNFetchBlobOpenFile.Mode.WRITE;
347+
else {
348+
accessMode = RNFetchBlobOpenFile.Mode.READWRITE;
349+
}
350+
try {
351+
Integer id = RNFetchBlobFS.openFile(path, accessMode);
352+
promise.resolve(id);
353+
}
354+
catch(Exception ex) {
355+
promise.reject(
356+
"RNFetchBlob failed to open file handle",
357+
DataConverter.exceptionToStringStackTrace(ex)
358+
);
359+
}
375360
}
376361
});
377362
}
378363

379364
@ReactMethod
380-
public void write(final String path, final String data, final String encoding, final int offset, final int length, final Promise promise) {
365+
public void readFromHandle(final int id, final String encoding, final int offset, final int length, final Promise promise) {
381366
fsThreadPool.execute(new Runnable() {
382367
@Override
383368
public void run() {
384-
RNFetchBlobFS fs = new RNFetchBlobFS(RCTContext);
385-
fs.write(path, encoding, data, offset, length, promise);
369+
try {
370+
RNFetchBlobOpenFile handle = RNFetchBlobFS.fileHandles.get(id);
371+
Object result = handle.read(encoding, offset, length);
372+
switch (encoding) {
373+
case RNFB_RESPONSE_BASE64:
374+
promise.resolve((String) result);
375+
break;
376+
case RNFB_RESPONSE_UTF8:
377+
promise.resolve((String) result);
378+
break;
379+
case RNFB_RESPONSE_ASCII:
380+
promise.resolve((ReadableArray) result);
381+
break;
382+
}
383+
}
384+
catch (Exception ex) {
385+
promise.reject(
386+
"RNFetchBlob failed to read from file handle",
387+
DataConverter.exceptionToStringStackTrace(ex)
388+
);
389+
}
390+
386391
}
387392
});
388393
}
389394

395+
@ReactMethod
396+
public void writeToHandle(final int id, final String encoding, final int offset, final String data, final Promise promise) {
397+
398+
fsThreadPool.execute(new Runnable() {
399+
@Override
400+
public void run() {
401+
try {
402+
RNFetchBlobOpenFile handle = RNFetchBlobFS.fileHandles.get(id);
403+
handle.write(encoding, data, offset);
404+
promise.resolve(null);
405+
}
406+
catch (Exception ex) {
407+
promise.reject(
408+
"RNFetchBlob failed to write tofile handle",
409+
DataConverter.exceptionToStringStackTrace(ex)
410+
);
411+
}
412+
}
413+
});
414+
}
415+
416+
@ReactMethod
417+
public void closeHandle(final int id, Promise promise) {
418+
try {
419+
RNFetchBlobOpenFile handle = RNFetchBlobFS.fileHandles.get(id);
420+
handle.close();
421+
promise.resolve(null);
422+
}
423+
catch (Exception ex) {
424+
promise.reject(
425+
"RNFetchBlob failed to close handle",
426+
DataConverter.exceptionToStringStackTrace(ex)
427+
);
428+
}
429+
}
430+
390431
public void getContentIntent(String mime, Promise promise) {
391432
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
392433
if(mime != null)

android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java

Lines changed: 9 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import java.util.Map;
4040
import java.util.UUID;
4141

42+
import static com.RNFetchBlob.RNFetchBlobOpenFile.*;
43+
4244
public class RNFetchBlobFS {
4345

4446
ReactApplicationContext mCtx;
@@ -47,6 +49,8 @@ public class RNFetchBlobFS {
4749
boolean append = false;
4850
OutputStream writeStreamInstance = null;
4951
static HashMap<String, RNFetchBlobFS> fileStreams = new HashMap<>();
52+
static HashMap<Integer, RNFetchBlobOpenFile> fileHandles = new HashMap<>();
53+
5054

5155
RNFetchBlobFS(ReactApplicationContext ctx) {
5256
this.mCtx = ctx;
@@ -100,7 +104,7 @@ static public void writeFile(String path, String encoding, String data, final bo
100104
}
101105
}
102106

103-
private static int writeFileToFileWithOffset(String source, String dest, int offset, boolean append) throws IOException {
107+
static int writeFileToFileWithOffset(String source, String dest, int offset, boolean append) throws IOException {
104108

105109
source = normalizePath(source);
106110
FileOutputStream fout = new FileOutputStream(dest, append);
@@ -915,65 +919,10 @@ static String normalizePath(String path) {
915919
return PathResolver.getRealPathFromURI(RNFetchBlob.RCTContext, uri);
916920
}
917921

918-
/**
919-
* Read {length} bytes from {path} from {offset} bytes.
920-
* @param path Source file URI
921-
* @param encoding The encoding of output data
922-
* @param offset Offset of the file.
923-
* @param length Length of data to read.
924-
* @return Result of the operation.
925-
* @throws Exception
926-
*/
927-
static Object readChunk(String path, String encoding, int offset, int length) throws Exception {
928-
path = normalizePath(path);
929-
if(path == null)
930-
return null;
931-
byte [] buffer = new byte[length];
932-
FileInputStream in = new FileInputStream(path);
933-
int read = in.read(buffer, offset, length);
934-
Object result = null;
935-
if(encoding.equalsIgnoreCase(RNFetchBlobConst.RNFB_RESPONSE_BASE64)) {
936-
result = DataConverter.byteToBase64(buffer, read);
937-
}
938-
else if(encoding.equalsIgnoreCase(RNFetchBlobConst.RNFB_RESPONSE_UTF8)) {
939-
result = DataConverter.byteToUTF8(buffer, read);
940-
}
941-
else if(encoding.equalsIgnoreCase(RNFetchBlobConst.RNFB_RESPONSE_ASCII)) {
942-
result = DataConverter.byteToRCTArray(buffer, read);
943-
}
944-
in.close();
945-
return result;
946-
947-
}
948-
949-
/**
950-
* Write specified data to destination start from {offset} bytes.
951-
* @param path Destination file path.
952-
* @param encoding Encoding of input data.
953-
* @param data Data to be written to file.
954-
* @param offset Offset of the operation.
955-
*/
956-
static void writeChunk(String path, String encoding, Object data, int offset) throws Exception {
957-
if(path == null)
958-
return;
959-
FileOutputStream out = new FileOutputStream(path);
960-
byte [] bytes = null;
961-
switch (encoding) {
962-
case RNFetchBlobConst.DATA_ENCODE_BASE64 :
963-
bytes = Base64.decode((String)data, 0);
964-
break;
965-
case RNFetchBlobConst.DATA_ENCODE_UTF8 :
966-
bytes = ((String)data).getBytes();
967-
break;
968-
case RNFetchBlobConst.DATA_ENCODE_ASCII :
969-
bytes = DataConverter.RCTArrayToBytes((ReadableArray) data);
970-
break;
971-
case RNFetchBlobConst.DATA_ENCODE_URI :
972-
writeFileToFileWithOffset((String)data, path, offset, false);
973-
return;
974-
}
975-
if(bytes != null)
976-
out.write(bytes, offset, bytes.length);
922+
static Integer openFile(String path, Mode mode) throws FileNotFoundException {
923+
Integer id = ++OpenFileId;
924+
RNFetchBlobFS.fileHandles.put(id, new RNFetchBlobOpenFile(path, mode));
925+
return id;
977926
}
978927

979928
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.RNFetchBlob;
2+
3+
import android.util.Base64;
4+
5+
import com.RNFetchBlob.Utils.DataConverter;
6+
import com.facebook.react.bridge.ReadableArray;
7+
8+
import java.io.FileInputStream;
9+
import java.io.FileNotFoundException;
10+
import java.io.FileOutputStream;
11+
import java.io.IOException;
12+
13+
import static com.RNFetchBlob.RNFetchBlobFS.normalizePath;
14+
import static com.RNFetchBlob.RNFetchBlobFS.writeFileToFileWithOffset;
15+
import static com.RNFetchBlob.RNFetchBlobOpenFile.Mode.*;
16+
17+
/**
18+
* Created by wkh237 on 2017/7/2.
19+
*/
20+
21+
public class RNFetchBlobOpenFile {
22+
23+
enum Mode {
24+
READ,
25+
WRITE,
26+
READWRITE
27+
}
28+
29+
private FileOutputStream writeStream;
30+
private FileInputStream readStream;
31+
private String path;
32+
private Mode accessMode;
33+
34+
static Integer OpenFileId = 0;
35+
36+
37+
RNFetchBlobOpenFile(String uri, Mode mode) throws FileNotFoundException {
38+
39+
this.path = normalizePath(uri);
40+
41+
if(mode == READ || mode == READWRITE) {
42+
this.readStream = new FileInputStream(path);
43+
}
44+
if( mode == WRITE || mode == READWRITE) {
45+
this.writeStream= new FileOutputStream(path);
46+
}
47+
this.accessMode = mode;
48+
49+
}
50+
51+
Object read(String encoding, int offset, int length) throws Exception {
52+
53+
54+
byte [] buffer = new byte[length];
55+
int read = this.readStream.read(buffer, offset, length);
56+
Object result = null;
57+
if(encoding.equalsIgnoreCase(RNFetchBlobConst.RNFB_RESPONSE_BASE64)) {
58+
result = DataConverter.byteToBase64(buffer, read);
59+
}
60+
else if(encoding.equalsIgnoreCase(RNFetchBlobConst.RNFB_RESPONSE_UTF8)) {
61+
result = DataConverter.byteToUTF8(buffer, read);
62+
}
63+
else if(encoding.equalsIgnoreCase(RNFetchBlobConst.RNFB_RESPONSE_ASCII)) {
64+
result = DataConverter.byteToRCTArray(buffer, read);
65+
}
66+
return result;
67+
68+
}
69+
70+
void write(String encoding, Object data, int offset) throws Exception {
71+
72+
byte [] bytes = null;
73+
switch (encoding) {
74+
case RNFetchBlobConst.DATA_ENCODE_BASE64 :
75+
bytes = Base64.decode((String)data, 0);
76+
break;
77+
case RNFetchBlobConst.DATA_ENCODE_UTF8 :
78+
bytes = ((String)data).getBytes();
79+
break;
80+
case RNFetchBlobConst.DATA_ENCODE_ASCII :
81+
bytes = DataConverter.RCTArrayToBytes((ReadableArray) data);
82+
break;
83+
case RNFetchBlobConst.DATA_ENCODE_URI :
84+
writeFileToFileWithOffset((String)data, this.path, offset, false);
85+
return;
86+
}
87+
if(bytes != null)
88+
this.writeStream.write(bytes, offset, bytes.length);
89+
90+
}
91+
92+
public void close() throws IOException {
93+
94+
switch (this.accessMode) {
95+
case READ:
96+
this.readStream.close();
97+
break;
98+
case WRITE:
99+
this.writeStream.close();
100+
break;
101+
case READWRITE:
102+
this.readStream.close();
103+
this.writeStream.close();
104+
break;
105+
}
106+
107+
}
108+
}

0 commit comments

Comments
 (0)