Skip to content

Commit bcf81df

Browse files
committed
Merge branch 'master' of github.com:itinance/react-native-fs
* 'master' of github.com:itinance/react-native-fs: (25 commits) fix touch() error on android Fixed Mtime Add missing flow annotations v2.5.2 (cocoapods related only) removed osx-version from Podspec added a note for cocoapods that we can't support it yet added a note for cocoapods that we can't support it yet Changes to the Podspec Changelog for README Version 2.5.0 - compat with RN 0.47.0 Added back for Backward-Compat but without @OverRide Version bump 2.4.0 removed createJSModules method (RN 0.47 breaking change) Add `createJSModules()` to be compatible with latest React. Update SDK compile and build tools to version 26. update README add read method with lenght and position params add `touch` method for changing file timestamps Remove createJSModules from package pod file path error ...
2 parents 01e8975 + a23a703 commit bcf81df

File tree

10 files changed

+232
-26
lines changed

10 files changed

+232
-26
lines changed

FS.common.js

100644100755
Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var NativeAppEventEmitter = require('react-native').NativeAppEventEmitter; // i
1313
var DeviceEventEmitter = require('react-native').DeviceEventEmitter; // Android
1414
var base64 = require('base-64');
1515
var utf8 = require('utf8');
16+
var isIOS = require('react-native').Platform.OS === 'ios';
1617

1718
var RNFSFileTypeRegular = RNFSManager.RNFSFileTypeRegular;
1819
var RNFSFileTypeDirectory = RNFSManager.RNFSFileTypeDirectory;
@@ -60,6 +61,8 @@ type DownloadFileOptions = {
6061
headers?: Headers; // An object of headers to be passed to the server
6162
background?: boolean; // iOS only
6263
progressDivider?: number;
64+
readTimeout?: number;
65+
connectionTimeout?: number;
6366
begin?: (res: DownloadBeginCallbackResult) => void;
6467
progress?: (res: DownloadProgressCallbackResult) => void;
6568
};
@@ -265,6 +268,36 @@ var RNFS = {
265268
return readFileGeneric(filepath, encodingOrOptions, RNFSManager.readFile);
266269
},
267270

271+
read(filepath: string, length: number = 0, position: number = 0, encodingOrOptions?: any): Promise<string> {
272+
var options = {
273+
encoding: 'utf8'
274+
};
275+
276+
if (encodingOrOptions) {
277+
if (typeof encodingOrOptions === 'string') {
278+
options.encoding = encodingOrOptions;
279+
} else if (typeof encodingOrOptions === 'object') {
280+
options = encodingOrOptions;
281+
}
282+
}
283+
284+
return RNFSManager.read(normalizeFilePath(filepath), length, position).then((b64) => {
285+
var contents;
286+
287+
if (options.encoding === 'utf8') {
288+
contents = utf8.decode(base64.decode(b64));
289+
} else if (options.encoding === 'ascii') {
290+
contents = base64.decode(b64);
291+
} else if (options.encoding === 'base64') {
292+
contents = b64;
293+
} else {
294+
throw new Error('Invalid encoding type "' + String(options.encoding) + '"');
295+
}
296+
297+
return contents;
298+
});
299+
},
300+
268301
// Android only
269302
readFileAssets(filepath: string, encodingOrOptions?: any): Promise<string> {
270303
if (!RNFSManager.readFileAssets) {
@@ -397,6 +430,8 @@ var RNFS = {
397430
if (options.headers && typeof options.headers !== 'object') throw new Error('downloadFile: Invalid value for property `headers`');
398431
if (options.background && typeof options.background !== 'boolean') throw new Error('downloadFile: Invalid value for property `background`');
399432
if (options.progressDivider && typeof options.progressDivider !== 'number') throw new Error('downloadFile: Invalid value for property `progressDivider`');
433+
if (options.readTimeout && typeof options.readTimeout !== 'number') throw new Error('downloadFile: Invalid value for property `readTimeout`');
434+
if (options.connectionTimeout && typeof options.connectionTimeout !== 'number') throw new Error('downloadFile: Invalid value for property `connectionTimeout`');
400435

401436
var jobId = getJobId();
402437
var subscriptions = [];
@@ -415,7 +450,9 @@ var RNFS = {
415450
toFile: normalizeFilePath(options.toFile),
416451
headers: options.headers || {},
417452
background: !!options.background,
418-
progressDivider: options.progressDivider || 0
453+
progressDivider: options.progressDivider || 0,
454+
readTimeout: options.readTimeout || 15000,
455+
connectionTimeout: options.connectionTimeout || 5000
419456
};
420457

421458
return {
@@ -479,6 +516,20 @@ var RNFS = {
479516
};
480517
},
481518

519+
touch(filepath: string, mtime?: Date, ctime?: Date): Promise<void> {
520+
if (ctime && !(ctime instanceof Date)) throw new Error('touch: Invalid value for argument `ctime`');
521+
if (mtime && !(mtime instanceof Date)) throw new Error('touch: Invalid value for argument `mtime`');
522+
var ctimeTime = 0;
523+
if (isIOS) {
524+
ctimeTime = ctime && ctime.getTime();
525+
}
526+
return RNFSManager.touch(
527+
normalizeFilePath(filepath),
528+
mtime && mtime.getTime(),
529+
ctimeTime
530+
);
531+
},
532+
482533
MainBundlePath: RNFSManager.RNFSMainBundlePath,
483534
CachesDirectoryPath: RNFSManager.RNFSCachesDirectoryPath,
484535
DocumentDirectoryPath: RNFSManager.RNFSDocumentDirectoryPath,

README.md

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,23 @@
22

33
Native filesystem access for react-native
44

5+
## Changes for v2.5
6+
- breaking change for RN 0.47 at android (https://github.com/facebook/react-native/releases/tag/v0.47.0)
7+
8+
## Changes for v2.4
9+
- Made new thread for other native processes [ANDROID] (https://github.com/itinance/react-native-fs/commit/ad36b078db9728489155a55c1b7daa42ed191945) thx to [codesinghanoop](https://github.com/codesinghanoop)
10+
- Upgrade gradle build tools to 25 (https://github.com/itinance/react-native-fs/commit/239bccb9d56fe9308daafb86920ed29eb9e5cfe4) thx to [markusguenther](https://github.com/markusguenther)
11+
- Fixed Podfile Path-Error (https://github.com/itinance/react-native-fs/commit/9fd51e7e977400f3194c100af88b4c25e7510530) thx to [colorfulberry](https://github.com/colorfulberry)
12+
- Add read-method with length and position params (https://github.com/itinance/react-native-fs/commit/a39c22be81f0c1f2263dbe60f3cd6cfcc902d2ac) thx to [simitti](https://github.com/simitii)
13+
14+
15+
516
## Changes for v2.3
617

718
- React-Native 0.40 is minimum required for compiling on iOS (otherwise install an older release, see below)
819
- Access to iOS-based "assets-library" is now supported with `copyAssetsFileIOS`
920
- `readDir` will return now creation- and modification-time of files as with `stat()` (thanks @Ignigena)
21+
- optional connectionTimeout and readTimeout-Settings on `downloadFile` for Android (thanks @drunksaint)
1022

1123
## Breaking change in v2.0
1224

@@ -43,18 +55,23 @@ At the command line, in your project folder, type:
4355

4456
Done! No need to worry about manually adding the library to your project.
4557

46-
### Adding with CocoaPods
58+
### ~~Adding with CocoaPods~~
59+
60+
Currently we don't support Cocoapods. If you are familiar with it, please feel free to submit PRs.
61+
More Info [here](https://github.com/itinance/react-native-fs/issues/308#issuecomment-319803126).
4762

48-
Add the RNFS pod to your list of application pods in your Podfile, using the path from the Podfile to the installed module:
63+
~~Add the RNFS pod to your list of application pods in your Podfile, using the path from the Podfile to the installed module:~~
4964

65+
~~
5066
```
51-
pod 'RNFS', :path => './node_modules/react-native-fs'
67+
pod 'RNFS', :path => '../node_modules/react-native-fs'
5268
```
5369

5470
Install pods as usual:
5571
```
5672
pod install
5773
```
74+
~~
5875

5976
### Adding Manually in XCode
6077

@@ -362,6 +379,12 @@ Reads the file at `path` and return contents. `encoding` can be one of `utf8` (d
362379

363380
Note: you will take quite a performance hit if you are reading big files
364381

382+
### `read(filepath: string, length = 0, position = 0, encodingOrOptions?: any): Promise<string>`
383+
384+
Reads `length` bytes from the given `position` of the file at `path` and returns contents. `encoding` can be one of `utf8` (default), `ascii`, `base64`. Use `base64` for reading binary files.
385+
386+
Note: reading big files piece by piece using this method may be useful in terms of performance.
387+
365388
### `readFileAssets(filepath:string, encoding?: string): Promise<string>`
366389

367390
Reads the file at `path` in the Android app's assets folder and return contents. `encoding` can be one of `utf8` (default), `ascii`, `base64`. Use `base64` for reading binary files.
@@ -440,6 +463,10 @@ Check in the Android assets folder if the item exists. `filepath` is the relativ
440463

441464
Reads the file at `path` and returns its checksum as determined by `algorithm`, which can be one of `md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha512`.
442465

466+
### `touch(filepath: string, mtime?: Date, ctime?: Date): Promise<string>`
467+
468+
Sets the modification timestamp `mtime` and creation timestamp `ctime` of the file at `filepath`. Setting `ctime` is only supported on iOS, android always sets both timestamps to `mtime`.
469+
443470
### `mkdir(filepath: string, options?: MkdirOptions): Promise<void>`
444471

445472
```
@@ -463,6 +490,8 @@ type DownloadFileOptions = {
463490
progressDivider?: number;
464491
begin?: (res: DownloadBeginCallbackResult) => void;
465492
progress?: (res: DownloadProgressCallbackResult) => void;
493+
connectionTimeout?: number // only supported on Android yet
494+
readTimeout?: number // only supported on Android yet
466495
};
467496
```
468497
```

RNFS.podspec

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ Pod::Spec.new do |s|
99
s.summary = pjson["description"]
1010
s.license = pjson["license"]
1111
s.author = { "Johannes Lumpe" => "johannes@lum.pe" }
12-
s.ios.deployment_target = '8.0'
13-
s.tvos.deployment_target = '9.0'
12+
13+
s.ios.deployment_target = '9.0'
14+
1415
s.source = { :git => "https://github.com/itinance/react-native-fs", :tag => "v#{s.version}" }
1516
s.source_files = '*.{h,m}'
1617
s.preserve_paths = "**/*.js"
1718

18-
s.dependency 'React/Core'
19+
s.dependency 'React'
1920

2021
end

RNFSManager.m

100644100755
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,51 @@ - (dispatch_queue_t)methodQueue
261261
resolve(base64Content);
262262
}
263263

264+
RCT_EXPORT_METHOD(read:(NSString *)filepath
265+
length: (NSInteger *)length
266+
position: (NSInteger *)position
267+
resolver:(RCTPromiseResolveBlock)resolve
268+
rejecter:(RCTPromiseRejectBlock)reject)
269+
{
270+
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filepath];
271+
272+
if (!fileExists) {
273+
return reject(@"ENOENT", [NSString stringWithFormat:@"ENOENT: no such file or directory, open '%@'", filepath], nil);
274+
}
275+
276+
NSError *error = nil;
277+
278+
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filepath error:&error];
279+
280+
if (error) {
281+
return [self reject:reject withError:error];
282+
}
283+
284+
if ([attributes objectForKey:NSFileType] == NSFileTypeDirectory) {
285+
return reject(@"EISDIR", @"EISDIR: illegal operation on a directory, read", nil);
286+
}
287+
288+
// Open the file handler.
289+
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:filepath];
290+
if (file == nil) {
291+
return reject(@"EISDIR", @"EISDIR: Could not open file for reading", nil);
292+
}
293+
294+
// Seek to the position if there is one.
295+
[file seekToFileOffset: (int)position];
296+
297+
NSData *content;
298+
if ((int)length > 0) {
299+
content = [file readDataOfLength: (int)length];
300+
} else {
301+
content = [file readDataToEndOfFile];
302+
}
303+
304+
NSString *base64Content = [content base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
305+
306+
resolve(base64Content);
307+
}
308+
264309
RCT_EXPORT_METHOD(hash:(NSString *)filepath
265310
algorithm:(NSString *)algorithm
266311
resolver:(RCTPromiseResolveBlock)resolve
@@ -685,6 +730,37 @@ - (dispatch_queue_t)methodQueue
685730
resolve(destination);
686731
}
687732

733+
RCT_EXPORT_METHOD(touch:(NSString*)filepath
734+
mtime:(NSDate *)mtime
735+
ctime:(NSDate *)ctime
736+
resolver:(RCTPromiseResolveBlock)resolve
737+
rejecter:(RCTPromiseRejectBlock)reject)
738+
{
739+
NSFileManager *manager = [NSFileManager defaultManager];
740+
BOOL exists = [manager fileExistsAtPath:filepath isDirectory:false];
741+
742+
if (!exists) {
743+
return reject(@"ENOENT", [NSString stringWithFormat:@"ENOENT: no such file, open '%@'", filepath], nil);
744+
}
745+
746+
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
747+
748+
if (mtime) {
749+
[attr setValue:mtime forKey:NSFileModificationDate];
750+
}
751+
if (ctime) {
752+
[attr setValue:ctime forKey:NSFileCreationDate];
753+
}
754+
755+
NSError *error = nil;
756+
BOOL success = [manager setAttributes:attr ofItemAtPath:filepath error:&error];
757+
758+
if (!success) {
759+
return [self reject:reject withError:error];
760+
}
761+
762+
resolve(nil);
763+
}
688764

689765

690766
- (NSNumber *)dateToTimeIntervalNumber:(NSDate *)date

android/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ buildscript {
1111
apply plugin: 'com.android.library'
1212

1313
android {
14-
compileSdkVersion 23
15-
buildToolsVersion "23.0.1"
14+
compileSdkVersion 25
15+
buildToolsVersion "25.0.0"
1616

1717
defaultConfig {
1818
minSdkVersion 16

android/src/main/java/com/rnfs/DownloadParams.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public interface OnDownloadProgress {
2323
public File dest;
2424
public ReadableMap headers;
2525
public float progressDivider;
26+
public int readTimeout;
27+
public int connectionTimeout;
2628
public OnTaskCompleted onTaskCompleted;
2729
public OnDownloadBegin onDownloadBegin;
2830
public OnDownloadProgress onDownloadProgress;

android/src/main/java/com/rnfs/Downloader.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,23 @@
2222
public class Downloader extends AsyncTask<DownloadParams, int[], DownloadResult> {
2323
private DownloadParams mParam;
2424
private AtomicBoolean mAbort = new AtomicBoolean(false);
25+
DownloadResult res;
2526

2627
protected DownloadResult doInBackground(DownloadParams... params) {
2728
mParam = params[0];
28-
29-
DownloadResult res = new DownloadResult();
30-
31-
try {
32-
this.download(mParam, res);
33-
mParam.onTaskCompleted.onTaskCompleted(res);
34-
} catch (Exception ex) {
35-
res.exception = ex;
36-
mParam.onTaskCompleted.onTaskCompleted(res);
37-
return res;
38-
}
29+
res = new DownloadResult();
30+
31+
new Thread(new Runnable() {
32+
public void run() {
33+
try {
34+
download(mParam, res);
35+
mParam.onTaskCompleted.onTaskCompleted(res);
36+
} catch (Exception ex) {
37+
res.exception = ex;
38+
mParam.onTaskCompleted.onTaskCompleted(res);
39+
}
40+
}
41+
}).start();
3942

4043
return res;
4144
}
@@ -56,8 +59,8 @@ private void download(DownloadParams param, DownloadResult res) throws Exception
5659
connection.setRequestProperty(key, value);
5760
}
5861

59-
connection.setConnectTimeout(5000);
60-
connection.setReadTimeout(15000);
62+
connection.setConnectTimeout(param.connectionTimeout);
63+
connection.setReadTimeout(param.readTimeout);
6164
connection.connect();
6265

6366
int statusCode = connection.getResponseCode();

0 commit comments

Comments
 (0)