Browse Source

Add stat lstat to IOS fs API

Ben Hsieh 8 years ago
parent
commit
a2971c0ff5

+ 30
- 0
src/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java View File

@@ -114,6 +114,36 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
114 114
         RNFetchBlobFS.removeSession(paths, callback);
115 115
     }
116 116
 
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
+
117 147
     @ReactMethod
118 148
     /**
119 149
      * @param path Stream file path

+ 108
- 12
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java View File

@@ -1,5 +1,7 @@
1 1
 package com.RNFetchBlob;
2 2
 
3
+import android.media.MediaScannerConnection;
4
+import android.net.Uri;
3 5
 import android.os.AsyncTask;
4 6
 import android.os.Environment;
5 7
 
@@ -7,6 +9,7 @@ import com.facebook.react.bridge.Arguments;
7 9
 import com.facebook.react.bridge.Callback;
8 10
 import com.facebook.react.bridge.ReactApplicationContext;
9 11
 import com.facebook.react.bridge.ReadableArray;
12
+import com.facebook.react.bridge.ReadableMap;
10 13
 import com.facebook.react.bridge.WritableArray;
11 14
 import com.facebook.react.bridge.WritableMap;
12 15
 import com.facebook.react.modules.core.DeviceEventManagerModule;
@@ -52,13 +55,21 @@ public class RNFetchBlobFS {
52 55
     static public void getSystemfolders(ReactApplicationContext ctx, Callback callback) {
53 56
         callback.invoke(
54 57
                 // document folder
55
-                String.valueOf(ctx.getFilesDir().getAbsolutePath()),
58
+                ctx.getFilesDir().getAbsolutePath(),
56 59
                 // cache folder
57
-                String.valueOf(ctx.getCacheDir().getAbsolutePath()),
60
+                ctx.getCacheDir().getAbsolutePath(),
58 61
                 // SD card folder
59
-                String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()),
62
+                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath(),
60 63
                 // 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()
62 73
         );
63 74
     }
64 75
 
@@ -155,7 +166,7 @@ public class RNFetchBlobFS {
155 166
     public void writeStream(String path, String encoding, boolean append, Callback callback) {
156 167
         File dest = new File(path);
157 168
         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");
159 170
             return;
160 171
         }
161 172
         try {
@@ -167,7 +178,7 @@ public class RNFetchBlobFS {
167 178
             this.writeStreamInstance = fs;
168 179
             callback.invoke(null, streamId);
169 180
         } 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());
171 182
         }
172 183
 
173 184
     }
@@ -255,7 +266,7 @@ public class RNFetchBlobFS {
255 266
     static void mkdir(String path, Callback callback) {
256 267
         File dest = new File(path);
257 268
         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");
259 270
             return;
260 271
         }
261 272
         dest.mkdirs();
@@ -275,7 +286,7 @@ public class RNFetchBlobFS {
275 286
 
276 287
             String destFolder = new File(dest).getPath();
277 288
             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");
279 290
                 return;
280 291
             }
281 292
 
@@ -314,7 +325,7 @@ public class RNFetchBlobFS {
314 325
     static void mv(String path, String dest, Callback callback) {
315 326
         File src = new File(path);
316 327
         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");
318 329
             return;
319 330
         }
320 331
         src.renameTo(new File(dest));
@@ -340,7 +351,7 @@ public class RNFetchBlobFS {
340 351
     static void ls(String path, Callback callback) {
341 352
         File src = new File(path);
342 353
         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");
344 355
             return;
345 356
         }
346 357
         String [] files = new File(path).list();
@@ -351,6 +362,65 @@ public class RNFetchBlobFS {
351 362
         callback.invoke(null, arg);
352 363
     }
353 364
 
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
+
354 424
     /**
355 425
      * Create new file at path
356 426
      * @param path
@@ -363,7 +433,7 @@ public class RNFetchBlobFS {
363 433
             File dest = new File(path);
364 434
             boolean created = dest.createNewFile();
365 435
             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");
367 437
                 return;
368 438
             }
369 439
             OutputStream ostream = new FileOutputStream(dest);
@@ -374,12 +444,18 @@ public class RNFetchBlobFS {
374 444
         }
375 445
     }
376 446
 
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
+     */
377 453
     static void createFileASCII(String path, ReadableArray data, Callback callback) {
378 454
         try {
379 455
             File dest = new File(path);
380 456
             boolean created = dest.createNewFile();
381 457
             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");
383 459
                 return;
384 460
             }
385 461
             OutputStream ostream = new FileOutputStream(dest);
@@ -395,6 +471,11 @@ public class RNFetchBlobFS {
395 471
         }
396 472
     }
397 473
 
474
+    /**
475
+     * Remove files in session.
476
+     * @param paths An array of file paths.
477
+     * @param callback JS contest callback
478
+     */
398 479
     static void removeSession(ReadableArray paths, Callback callback) {
399 480
 
400 481
         AsyncTask<ReadableArray, Integer, Integer> task = new AsyncTask<ReadableArray, Integer, Integer>() {
@@ -450,6 +531,21 @@ public class RNFetchBlobFS {
450 531
         eventData.putString("detail", data);
451 532
         this.emitter.emit("RNFetchBlobStream" + taskId, eventData);
452 533
     }
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
+
453 549
 }
454 550
 
455 551
 

+ 62
- 0
src/ios/RNFetchBlob/RNFetchBlob.m View File

@@ -106,6 +106,19 @@ NSMutableDictionary *fileStreams = nil;
106 106
     return err == nil;
107 107
 }
108 108
 
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
+
109 122
 + (BOOL) exists:(NSString *) path {
110 123
     return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:NULL];
111 124
 }
@@ -823,6 +836,55 @@ RCT_EXPORT_METHOD(ls:(NSString *)path callback:(RCTResponseSenderBlock) callback
823 836
     
824 837
 }
825 838
 
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
+
826 888
 RCT_EXPORT_METHOD(cp:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
827 889
     NSError * error = nil;
828 890
     BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];