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

Commit a2971c0

Browse files
committed
Add stat lstat to IOS fs API
1 parent 2cbb8f7 commit a2971c0

File tree

3 files changed

+200
-12
lines changed

3 files changed

+200
-12
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,36 @@ public void removeSession(ReadableArray paths, Callback callback) {
114114
RNFetchBlobFS.removeSession(paths, callback);
115115
}
116116

117+
@ReactMethod
118+
public void lstat(String path, Callback callback) {
119+
RNFetchBlobFS.ls(path, callback);
120+
}
121+
122+
@ReactMethod
123+
public void stat(String path, Callback callback) {
124+
RNFetchBlobFS.stat(path, callback);
125+
}
126+
127+
@ReactMethod
128+
public void scanFile(ReadableMap pairs, Callback callback) {
129+
ReadableMapKeySetIterator it = pairs.keySetIterator();
130+
WritableArray path = Arguments.createArray();
131+
WritableArray mimes = Arguments.createArray();
132+
while(it.hasNextKey()) {
133+
String key = pairs.keySetIterator().nextKey();
134+
path.pushString(key);
135+
String mime = pairs.getString(key);
136+
mimes.pushString(mime);
137+
}
138+
String [] p = new String[path.size()];
139+
String [] m = new String[path.size()];
140+
for(int i =0;i<path.size();i++) {
141+
p[i] = path.getString(i);
142+
m[i] = mimes.getString(i);
143+
}
144+
new RNFetchBlobFS(this.getReactApplicationContext()).scanFile(p, m, callback);
145+
}
146+
117147
@ReactMethod
118148
/**
119149
* @param path Stream file path

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

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package com.RNFetchBlob;
22

3+
import android.media.MediaScannerConnection;
4+
import android.net.Uri;
35
import android.os.AsyncTask;
46
import android.os.Environment;
57

68
import com.facebook.react.bridge.Arguments;
79
import com.facebook.react.bridge.Callback;
810
import com.facebook.react.bridge.ReactApplicationContext;
911
import com.facebook.react.bridge.ReadableArray;
12+
import com.facebook.react.bridge.ReadableMap;
1013
import com.facebook.react.bridge.WritableArray;
1114
import com.facebook.react.bridge.WritableMap;
1215
import com.facebook.react.modules.core.DeviceEventManagerModule;
@@ -52,13 +55,21 @@ public class RNFetchBlobFS {
5255
static public void getSystemfolders(ReactApplicationContext ctx, Callback callback) {
5356
callback.invoke(
5457
// document folder
55-
String.valueOf(ctx.getFilesDir().getAbsolutePath()),
58+
ctx.getFilesDir().getAbsolutePath(),
5659
// cache folder
57-
String.valueOf(ctx.getCacheDir().getAbsolutePath()),
60+
ctx.getCacheDir().getAbsolutePath(),
5861
// SD card folder
59-
String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()),
62+
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath(),
6063
// Download folder
61-
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
64+
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(),
65+
// Picture
66+
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath(),
67+
// Music
68+
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath(),
69+
// Movies
70+
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath(),
71+
// Ringtones
72+
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES).getAbsolutePath()
6273
);
6374
}
6475

@@ -155,7 +166,7 @@ protected Integer doInBackground(String ... args) {
155166
public void writeStream(String path, String encoding, boolean append, Callback callback) {
156167
File dest = new File(path);
157168
if(!dest.exists() || dest.isDirectory()) {
158-
callback.invoke("target path `" + path + "` may not exists or it's a folder");
169+
callback.invoke("write stream error: target path `" + path + "` may not exists or it's a folder");
159170
return;
160171
}
161172
try {
@@ -167,7 +178,7 @@ public void writeStream(String path, String encoding, boolean append, Callback c
167178
this.writeStreamInstance = fs;
168179
callback.invoke(null, streamId);
169180
} catch(Exception err) {
170-
callback.invoke("failed to create write stream at path `"+path+"` "+ err.getLocalizedMessage());
181+
callback.invoke("write stream error: failed to create write stream at path `"+path+"` "+ err.getLocalizedMessage());
171182
}
172183

173184
}
@@ -255,7 +266,7 @@ static void unlink(String path, Callback callback) {
255266
static void mkdir(String path, Callback callback) {
256267
File dest = new File(path);
257268
if(dest.exists()) {
258-
callback.invoke("failed to create folder at `" + path + "` folder already exists");
269+
callback.invoke("mkdir error: failed to create folder at `" + path + "` folder already exists");
259270
return;
260271
}
261272
dest.mkdirs();
@@ -275,7 +286,7 @@ static void cp(String path, String dest, Callback callback) {
275286

276287
String destFolder = new File(dest).getPath();
277288
if(!new File(path).exists()) {
278-
callback.invoke("source file at path`" + path + "` not exists");
289+
callback.invoke("cp error: source file at path`" + path + "` not exists");
279290
return;
280291
}
281292

@@ -314,7 +325,7 @@ static void cp(String path, String dest, Callback callback) {
314325
static void mv(String path, String dest, Callback callback) {
315326
File src = new File(path);
316327
if(!src.exists()) {
317-
callback.invoke("source file at path `" + path + "` does not exists");
328+
callback.invoke("mv error: source file at path `" + path + "` does not exists");
318329
return;
319330
}
320331
src.renameTo(new File(dest));
@@ -340,7 +351,7 @@ static void exists(String path, Callback callback) {
340351
static void ls(String path, Callback callback) {
341352
File src = new File(path);
342353
if(!src.exists() || !src.isDirectory()) {
343-
callback.invoke("failed to list path `" + path + "` for it is not exist or it is not a folder");
354+
callback.invoke("ls error: failed to list path `" + path + "` for it is not exist or it is not a folder");
344355
return;
345356
}
346357
String [] files = new File(path).list();
@@ -351,6 +362,65 @@ static void ls(String path, Callback callback) {
351362
callback.invoke(null, arg);
352363
}
353364

365+
static void lstat(String path, final Callback callback) {
366+
File src = new File(path);
367+
new AsyncTask<String, Integer, Integer>() {
368+
@Override
369+
protected Integer doInBackground(String ...args) {
370+
WritableArray res = Arguments.createArray();
371+
File src = new File(args[0]);
372+
if(!src.exists()) {
373+
callback.invoke("lstat error: failed to list path `" + args[0] + "` for it is not exist or it is not a folder");
374+
return 0;
375+
}
376+
if(src.isDirectory()) {
377+
String [] files = src.list();
378+
for(String p : files) {
379+
res.pushMap(statFile ( src.getPath() + p));
380+
}
381+
}
382+
else {
383+
res.pushMap(statFile(src.getAbsolutePath()));
384+
}
385+
callback.invoke(null, res);
386+
return 0;
387+
}
388+
}.execute(path);
389+
}
390+
391+
/**
392+
* show status of a file or directory
393+
* @param path
394+
* @param callback
395+
*/
396+
static void stat(String path, Callback callback) {
397+
File target = new File(path);
398+
if(!target.exists()) {
399+
callback.invoke("stat error: file "+path+" does not exists");
400+
return;
401+
}
402+
WritableMap stat = Arguments.createMap();
403+
stat.putString("filename", target.getName());
404+
stat.putString("path", target.getPath());
405+
stat.putString("type", target.isDirectory() ? "directory" : "file");
406+
stat.putInt("size", (int)target.length());
407+
stat.putInt("lastModified", (int)target.lastModified());
408+
callback.invoke(null, stat);
409+
}
410+
411+
void scanFile(String [] path, String[] mimes, final Callback callback) {
412+
try {
413+
MediaScannerConnection.scanFile(mCtx, path, mimes, new MediaScannerConnection.OnScanCompletedListener() {
414+
@Override
415+
public void onScanCompleted(String s, Uri uri) {
416+
callback.invoke(null, true);
417+
}
418+
});
419+
} catch(Exception err) {
420+
callback.invoke(err.getLocalizedMessage(), null);
421+
}
422+
}
423+
354424
/**
355425
* Create new file at path
356426
* @param path
@@ -363,7 +433,7 @@ static void createFile(String path, String data, String encoding, Callback callb
363433
File dest = new File(path);
364434
boolean created = dest.createNewFile();
365435
if(!created) {
366-
callback.invoke("failed to create file at path `" + path + "` for its parent path may not exists");
436+
callback.invoke("create file error: failed to create file at path `" + path + "` for its parent path may not exists");
367437
return;
368438
}
369439
OutputStream ostream = new FileOutputStream(dest);
@@ -374,12 +444,18 @@ static void createFile(String path, String data, String encoding, Callback callb
374444
}
375445
}
376446

447+
/**
448+
* Create file for ASCII encoding
449+
* @param path Path of new file.
450+
* @param data Content of new file
451+
* @param callback JS context callback
452+
*/
377453
static void createFileASCII(String path, ReadableArray data, Callback callback) {
378454
try {
379455
File dest = new File(path);
380456
boolean created = dest.createNewFile();
381457
if(!created) {
382-
callback.invoke("failed to create file at path `" + path + "` for its parent path may not exists");
458+
callback.invoke("create file error: failed to create file at path `" + path + "` for its parent path may not exists");
383459
return;
384460
}
385461
OutputStream ostream = new FileOutputStream(dest);
@@ -395,6 +471,11 @@ static void createFileASCII(String path, ReadableArray data, Callback callback)
395471
}
396472
}
397473

474+
/**
475+
* Remove files in session.
476+
* @param paths An array of file paths.
477+
* @param callback JS contest callback
478+
*/
398479
static void removeSession(ReadableArray paths, Callback callback) {
399480

400481
AsyncTask<ReadableArray, Integer, Integer> task = new AsyncTask<ReadableArray, Integer, Integer>() {
@@ -450,6 +531,21 @@ void emitFSData(String taskId, String event, String data) {
450531
eventData.putString("detail", data);
451532
this.emitter.emit("RNFetchBlobStream" + taskId, eventData);
452533
}
534+
535+
static WritableMap statFile(String path) {
536+
File target = new File(path);
537+
if(!target.exists()) {
538+
return null;
539+
}
540+
WritableMap stat = Arguments.createMap();
541+
stat.putString("filename", target.getName());
542+
stat.putString("path", target.getPath());
543+
stat.putString("type", target.isDirectory() ? "directory" : "file");
544+
stat.putInt("size", (int)target.length());
545+
stat.putInt("lastModified", (int)target.lastModified());
546+
return stat;
547+
}
548+
453549
}
454550

455551

src/ios/RNFetchBlob/RNFetchBlob.m

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,19 @@ + (BOOL) mkdir:(NSString *) path {
106106
return err == nil;
107107
}
108108

109+
+ (NSData *) stat:(NSString *) path error:(NSError **) error{
110+
NSMutableData *stat = [[NSMutableData alloc]init];
111+
NSFileManager * fm = [NSFileManager defaultManager];
112+
NSData * info = [fm attributesOfItemAtPath:path error:&error];
113+
[stat setValue:[info valueForKey:NSFileSystemSize] forKey:@"size"];
114+
[stat setValue:path forKey:@"path"];
115+
[stat setValue:[path stringByDeletingPathExtension] forKey:@"filename"];
116+
NSDate * lastModified;
117+
[[NSURL fileURLWithPath:path] getResourceValue:&lastModified forKey:NSURLContentModificationDateKey error:&error];
118+
[stat setValue:lastModified forKey:@"lastModified"];
119+
return stat;
120+
}
121+
109122
+ (BOOL) exists:(NSString *) path {
110123
return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:NULL];
111124
}
@@ -823,6 +836,55 @@ - (id) init {
823836

824837
}
825838

839+
RCT_EXPORT_METHOD(stat:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
840+
NSFileManager* fm = [NSFileManager defaultManager];
841+
BOOL exist = nil;
842+
BOOL isDir = nil;
843+
NSError * error = nil;
844+
exist = [fm fileExistsAtPath:path isDirectory:&isDir];
845+
if(exist == NO) {
846+
callback(@[[NSString stringWithFormat:@"failed to list path `%@` for it is not exist or it is not exist", path]]);
847+
return ;
848+
}
849+
NSData * res = [FetchBlobFS stat:path error:&error];
850+
851+
if(error == nil)
852+
callback(@[[NSNull null], res]);
853+
else
854+
callback(@[[error localizedDescription], [NSNull null]]);
855+
856+
}
857+
858+
RCT_EXPORT_METHOD(lstat:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
859+
NSFileManager* fm = [NSFileManager defaultManager];
860+
BOOL exist = nil;
861+
BOOL isDir = nil;
862+
exist = [fm fileExistsAtPath:path isDirectory:&isDir];
863+
if(exist == NO) {
864+
callback(@[[NSString stringWithFormat:@"failed to list path `%@` for it is not exist or it is not exist", path]]);
865+
return ;
866+
}
867+
NSError * error = nil;
868+
NSArray * files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
869+
870+
NSMutableArray * res = [NSMutableArray alloc];
871+
if(isDir == YES) {
872+
for(NSString * p in files) {
873+
NSString * filePath = [NSString stringWithFormat:@"%@/%@", path, p];
874+
[res addObject:[FetchBlobFS stat:filePath error:&error]];
875+
}
876+
}
877+
else {
878+
[res addObject:[FetchBlobFS stat:path error:&error]];
879+
}
880+
881+
if(error == nil)
882+
callback(@[[NSNull null], res == nil ? [NSNull null] :res ]);
883+
else
884+
callback(@[[error localizedDescription], [NSNull null]]);
885+
886+
}
887+
826888
RCT_EXPORT_METHOD(cp:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
827889
NSError * error = nil;
828890
BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];

0 commit comments

Comments
 (0)