Browse Source

Code refactor

Ben Hsieh 8 years ago
parent
commit
2cbb8f7d5b

+ 12
- 0
src/class/RNFetchBlobFile.js View File

1
+import {
2
+  NativeModules,
3
+  DeviceEventEmitter,
4
+  NativeAppEventEmitter,
5
+} from 'react-native'
6
+
7
+const RNFetchBlob = NativeModules.RNFetchBlob
8
+const emitter = DeviceEventEmitter
9
+
10
+export default class RNFetchBlobFile {
11
+
12
+}

+ 76
- 0
src/class/RNFetchBlobReadStream.js View File

1
+import {
2
+  NativeModules,
3
+  DeviceEventEmitter,
4
+  NativeAppEventEmitter,
5
+} from 'react-native'
6
+
7
+const RNFetchBlob = NativeModules.RNFetchBlob
8
+const emitter = DeviceEventEmitter
9
+
10
+export default class RNFetchBlobReadStream {
11
+
12
+  path : string;
13
+  encoding : 'utf8' | 'ascii' | 'base64';
14
+  bufferSize : ?number;
15
+  closed : boolean;
16
+
17
+  constructor(path:string, encoding:string, bufferSize?:?number) {
18
+    if(!path)
19
+      throw Error('RNFetchBlob could not open file stream with empty `path`')
20
+    this.encoding = encoding || 'utf8'
21
+    this.bufferSize = bufferSize
22
+    this.path = path
23
+    this.closed = false
24
+    this._onData = () => {}
25
+    this._onEnd = () => {}
26
+    this._onError = () => {}
27
+
28
+    // register for file stream event
29
+    let subscription = emitter.addListener(`RNFetchBlobStream+${this.path}`, (e) => {
30
+    
31
+      let {event, detail} = e
32
+      if(this._onData && event === 'data')
33
+        this._onData(detail)
34
+      else if (this._onEnd && event === 'end') {
35
+        this._onEnd(detail)
36
+      }
37
+      else {
38
+        if(this._onError)
39
+          this._onError(detail)
40
+        else
41
+          throw new Error(detail)
42
+      }
43
+      // when stream closed or error, remove event handler
44
+      if (event === 'error' || event === 'end') {
45
+        subscription.remove()
46
+        this.closed = true
47
+      }
48
+    })
49
+
50
+  }
51
+
52
+  open() {
53
+    if(!this.closed)
54
+      RNFetchBlob.readStream(this.path, this.encoding, this.bufferSize || 0)
55
+    else
56
+      throw new Error('Stream closed')
57
+  }
58
+
59
+  onData(fn) {
60
+    if(this.encoding.toLowerCase() === 'ascii')
61
+      this._onData = (data) => {
62
+        fn(JSON.parse(data))
63
+      }
64
+    else
65
+      this._onData = fn
66
+  }
67
+
68
+  onError(fn) {
69
+    this._onError = fn
70
+  }
71
+
72
+  onEnd (fn) {
73
+    this._onEnd = fn
74
+  }
75
+
76
+}

+ 66
- 0
src/class/RNFetchBlobSession.js View File

1
+/**
2
+ * Session class
3
+ * @class RNFetchBlobSession
4
+ */
5
+
6
+import {
7
+ NativeModules,
8
+ DeviceEventEmitter,
9
+ NativeAppEventEmitter,
10
+} from 'react-native'
11
+
12
+const RNFetchBlob = NativeModules.RNFetchBlob
13
+const emitter = DeviceEventEmitter
14
+
15
+export default class RNFetchBlobSession {
16
+
17
+  add : (path:string) => RNFetchBlobSession;
18
+  remove : (path:string) => RNFetchBlobSession;
19
+  dispose : () => Promise;
20
+  list : () => Array<string>;
21
+  name : string;
22
+
23
+  constructor(name:string, list:Array<string>) {
24
+    this.name = name
25
+    if(!sessions[name]) {
26
+      if(Array.isArray(list))
27
+      sessions[name] = list
28
+      else
29
+      sessions[name] = []
30
+    }
31
+  }
32
+
33
+  add(path:string):RNFetchBlobSession {
34
+    sessions[this.name].push(path)
35
+    return this
36
+  }
37
+
38
+  remove(path:string):RNFetchBlobSession {
39
+    let list = sessions[this.name]
40
+    for(let i in list) {
41
+      if(list[i] === path) {
42
+        sessions[this.name].splice(i, 1)
43
+        break;
44
+      }
45
+    }
46
+    return this
47
+  }
48
+
49
+  list():Array<string> {
50
+    return sessions[this.name]
51
+  }
52
+
53
+  dispose():Promise {
54
+    return new Promise((resolve, reject) => {
55
+      RNFetchBlob.removeSession(sessions[this.name], (err) => {
56
+        if(err)
57
+          reject(err)
58
+        else {
59
+          delete sessions[this.name]
60
+          resolve()
61
+        }
62
+      })
63
+    })
64
+  }
65
+
66
+}

+ 54
- 0
src/class/RNFetchBlobWriteStream.js View File

1
+import {
2
+ NativeModules,
3
+ DeviceEventEmitter,
4
+ NativeAppEventEmitter,
5
+} from 'react-native'
6
+
7
+const RNFetchBlob = NativeModules.RNFetchBlob
8
+const emitter = DeviceEventEmitter
9
+
10
+export default class RNFetchBlobWriteStream {
11
+
12
+  id : string;
13
+  encoding : string;
14
+  append : bool;
15
+
16
+  constructor(streamId:string, encoding:string, append:string) {
17
+    this.id = streamId
18
+    this.encoding = encoding
19
+    this.append = append
20
+  }
21
+
22
+  write(data:string) {
23
+    return new Promise((resolve, reject) => {
24
+      try {
25
+        let method = this.encoding === 'ascii' ? 'writeArrayChunk' : 'writeChunk'
26
+        if(this.encoding.toLocaleLowerCase() === 'ascii' && !Array.isArray(data)) {
27
+            reject('ascii input data must be an Array')
28
+            return
29
+        }
30
+        RNFetchBlob[method](this.id, data, (error) => {
31
+          if(error)
32
+            reject(error)
33
+          else
34
+            resolve()
35
+        })
36
+      } catch(err) {
37
+        reject(err)
38
+      }
39
+    })
40
+  }
41
+
42
+  close() {
43
+    return new Promise((resolve, reject) => {
44
+      try {
45
+        RNFetchBlob.closeStream(this.id, () => {
46
+          resolve()
47
+        })
48
+      } catch (err) {
49
+        reject(err)
50
+      }
51
+    })
52
+  }
53
+
54
+}

+ 36
- 154
src/fs.js View File

10
   DeviceEventEmitter,
10
   DeviceEventEmitter,
11
   NativeAppEventEmitter,
11
   NativeAppEventEmitter,
12
 } from 'react-native'
12
 } from 'react-native'
13
+import RNFetchBlobSession from './class/RNFetchBlobSession'
14
+import RNFetchBlobWriteStream from './class/RNFetchBlobWriteStream'
15
+import RNFetchBlobReadStream from './class/RNFetchBlobReadStream'
16
+import RNFetchBlobFile from './class/RNFetchBlobFile'
13
 import type {
17
 import type {
14
   RNFetchBlobNative,
18
   RNFetchBlobNative,
15
   RNFetchBlobConfig,
19
   RNFetchBlobConfig,
87
   path : string,
91
   path : string,
88
   encoding : 'utf8' | 'ascii' | 'base64',
92
   encoding : 'utf8' | 'ascii' | 'base64',
89
   append? : ?bool,
93
   append? : ?bool,
90
-):Promise<WriteStream> {
94
+):Promise<RNFetchBlobWriteStream> {
91
   if(!path)
95
   if(!path)
92
     throw Error('RNFetchBlob could not open file stream with empty `path`')
96
     throw Error('RNFetchBlob could not open file stream with empty `path`')
93
-
97
+  encoding = encoding || 'utf8'
98
+  append = append || false
94
   return new Promise((resolve, reject) => {
99
   return new Promise((resolve, reject) => {
95
     RNFetchBlob.writeStream(path, encoding || 'base64', append || false, (err, streamId:string) => {
100
     RNFetchBlob.writeStream(path, encoding || 'base64', append || false, (err, streamId:string) => {
96
       if(err)
101
       if(err)
97
         reject(err)
102
         reject(err)
98
       else
103
       else
99
-        resolve(new WriteStream(streamId, encoding))
104
+        resolve(new RNFetchBlobWriteStream(streamId, encoding))
100
     })
105
     })
101
   })
106
   })
102
 }
107
 }
112
   path : string,
117
   path : string,
113
   encoding : 'utf8' | 'ascii' | 'base64',
118
   encoding : 'utf8' | 'ascii' | 'base64',
114
   bufferSize? : ?number
119
   bufferSize? : ?number
115
-):RNFetchBlobStream {
116
-
117
-  if(!path)
118
-    throw Error('RNFetchBlob could not open file stream with empty `path`')
119
-  encoding = encoding || 'utf8'
120
-  let stream:RNFetchBlobStream = {
121
-    // parse JSON array when encoding is ASCII
122
-    onData : function(fn) {
123
-      if(encoding.toLowerCase() === 'ascii')
124
-        this._onData = (data) => {
125
-          fn(JSON.parse(data))
126
-        }
127
-      else
128
-        this._onData = fn
129
-    },
130
-    onError : function(fn) {
131
-      this._onError = fn
132
-    },
133
-    onEnd : function(fn) {
134
-      this._onEnd = fn
135
-    },
136
-  }
137
-
138
-  // register for file stream event
139
-  let subscription = emitter.addListener(`RNFetchBlobStream+${path}`, (e) => {
140
-
141
-    let {event, detail} = e
142
-    if(stream._onData && event === 'data')
143
-      stream._onData(detail)
144
-    else if (stream._onEnd && event === 'end') {
145
-      stream._onEnd(detail)
146
-    }
147
-    else {
148
-      if(stream._onError)
149
-        stream._onError(detail)
150
-      else
151
-        throw new Error(detail)
152
-    }
153
-    // when stream closed or error, remove event handler
154
-    if (event === 'error' || event === 'end') {
155
-      subscription.remove()
156
-    }
157
-  })
158
-
159
-  RNFetchBlob.readStream(path, encoding, bufferSize || 0)
160
-  return stream
161
-
120
+):Promise<RNFetchBlobReadStream> {
121
+  return Promise.resolve(new RNFetchBlobReadStream(path, encoding, bufferSize))
162
 }
122
 }
163
 
123
 
124
+/**
125
+ * Create a directory.
126
+ * @param  {string} path Path of directory to be created
127
+ * @return {Promise}
128
+ */
164
 function mkdir(path:string):Promise {
129
 function mkdir(path:string):Promise {
165
 
130
 
166
   return new Promise((resolve, reject) => {
131
   return new Promise((resolve, reject) => {
174
 
139
 
175
 }
140
 }
176
 
141
 
142
+/**
143
+ * Show statistic data of a path.
144
+ * @param  {string} path Target path
145
+ * @return {RNFetchBlobFile}
146
+ */
147
+function stat(path:string):Promise<RNFetchBlobFile> {
148
+
149
+}
150
+
151
+/**
152
+ * Android only method, request media scanner to scan the file.
153
+ * @param  {Array<string>} paths Paths of files to be scanned.
154
+ * @param  {Array<string>} mimes Optional array of MIME types for each path.
155
+ *                               If mimeType is null, then the mimeType will be
156
+ *                               inferred from the file extension.
157
+ * @return {Promise}
158
+ */
159
+function scanFile(paths:Array<string>, mimes: Array<string>):Promise {
160
+
161
+}
162
+
177
 function cp(path:string, dest:string):Promise<boolean> {
163
 function cp(path:string, dest:string):Promise<boolean> {
178
   return new Promise((resolve, reject) => {
164
   return new Promise((resolve, reject) => {
179
     RNFetchBlob.cp(path, dest, (err, res) => {
165
     RNFetchBlob.cp(path, dest, (err, res) => {
256
 
242
 
257
 }
243
 }
258
 
244
 
259
-
260
-/**
261
- * Session class
262
- * @class RNFetchBlobSession
263
- */
264
-class RNFetchBlobSession {
265
-
266
-  add : (path:string) => RNFetchBlobSession;
267
-  remove : (path:string) => RNFetchBlobSession;
268
-  dispose : () => Promise;
269
-  list : () => Array<string>;
270
-  name : string;
271
-
272
-  constructor(name:string, list:Array<string>) {
273
-    this.name = name
274
-    if(!sessions[name]) {
275
-      if(Array.isArray(list))
276
-      sessions[name] = list
277
-      else
278
-      sessions[name] = []
279
-    }
280
-  }
281
-
282
-  add(path:string):RNFetchBlobSession {
283
-    sessions[this.name].push(path)
284
-    return this
285
-  }
286
-
287
-  remove(path:string):RNFetchBlobSession {
288
-    let list = sessions[this.name]
289
-    for(let i in list) {
290
-      if(list[i] === path) {
291
-        sessions[this.name].splice(i, 1)
292
-        break;
293
-      }
294
-    }
295
-    return this
296
-  }
297
-
298
-  list():Array<string> {
299
-    return sessions[this.name]
300
-  }
301
-
302
-  dispose():Promise {
303
-    return new Promise((resolve, reject) => {
304
-      RNFetchBlob.removeSession(sessions[this.name], (err) => {
305
-        if(err)
306
-          reject(err)
307
-        else {
308
-          delete sessions[this.name]
309
-          resolve()
310
-        }
311
-      })
312
-    })
313
-  }
314
-
315
-}
316
-
317
-class WriteStream {
318
-
319
-  id : string;
320
-  encoding : string;
321
-  append : bool;
322
-
323
-  constructor(streamId:string, encoding:string, append:string) {
324
-    this.id = streamId
325
-    this.encoding = encoding
326
-    this.append = append
327
-  }
328
-
329
-  write(data:string) {
330
-    return new Promise((resolve, reject) => {
331
-      try {
332
-        let method = this.encoding === 'ascii' ? 'writeArrayChunk' : 'writeChunk'
333
-        if(this.encoding.toLocaleLowerCase() === 'ascii' && !Array.isArray(data)) {
334
-            reject('ascii input data must be an Array')
335
-            return
336
-        }
337
-        RNFetchBlob[method](this.id, data, (error) => {
338
-          if(error)
339
-            reject(error)
340
-          else
341
-            resolve()
342
-        })
343
-      } catch(err) {
344
-        reject(err)
345
-      }
346
-    })
347
-  }
348
-
349
-  close() {
350
-    return new Promise((resolve, reject) => {
351
-      try {
352
-        RNFetchBlob.closeStream(this.id, () => {
353
-          resolve()
354
-        })
355
-      } catch (err) {
356
-        reject(err)
357
-      }
358
-    })
359
-  }
360
-
361
-}
362
-
363
 export default {
245
 export default {
364
   RNFetchBlobSession,
246
   RNFetchBlobSession,
365
   unlink,
247
   unlink,

+ 33
- 27
test/test-0.5.x.js View File

47
 
47
 
48
 describe('Read cached file via file stream', (report, done) => {
48
 describe('Read cached file via file stream', (report, done) => {
49
   let data = 'data:image/png;base64, '
49
   let data = 'data:image/png;base64, '
50
-  let stream = fs.readStream(tmpFilePath, 'base64')
51
-  stream.onData((chunk) => {
52
-    data += chunk
53
-  })
54
-  stream.onEnd(() => {
55
-    report(
56
-      <Assert key="image should have value"
57
-        expect={0}
58
-        comparer={Comparer.smaller}
59
-        actual={data.length}/>,
60
-      <Info key="image from read stream">
61
-        <Image source={{uri : data}} style={styles.image}/>
62
-      </Info>)
63
-    done()
64
-  })
65
-  stream.onError((err) => {
66
-    console.log('stream err', err)
67
-  })
50
+  fs.readStream(tmpFilePath, 'base64')
51
+    .then((stream) => {
52
+      stream.open()
53
+      stream.onData((chunk) => {
54
+        data += chunk
55
+      })
56
+      stream.onEnd(() => {
57
+        report(
58
+          <Assert key="image should have value"
59
+            expect={0}
60
+            comparer={Comparer.smaller}
61
+            actual={data.length}/>,
62
+          <Info key="image from read stream">
63
+            <Image source={{uri : data}} style={styles.image}/>
64
+          </Info>)
65
+        done()
66
+      })
67
+      stream.onError((err) => {
68
+        console.log('stream err', err)
69
+      })
70
+    })
68
 })
71
 })
69
 
72
 
70
 describe('File stream reader error should be able to handled', (report, done) => {
73
 describe('File stream reader error should be able to handled', (report, done) => {
71
-  let stream = fs.readStream('^_^ not exists', 'base64')
72
-  stream.onError((err) => {
73
-    report(<Info key="error message">
74
-      <Text>
75
-        {err}
76
-      </Text>
77
-    </Info>)
78
-    done()
74
+  fs.readStream('^_^ not exists', 'base64')
75
+    .then((stream) => {
76
+      stream.open()
77
+      stream.onError((err) => {
78
+        report(<Info key="error message">
79
+          <Text>
80
+            {err}
81
+          </Text>
82
+        </Info>)
83
+        done()
79
 
84
 
80
-  })
85
+      })
86
+    })
81
 })
87
 })
82
 
88
 
83
 let localFile = null
89
 let localFile = null

+ 110
- 92
test/test-fs.js View File

77
 
77
 
78
   fs.createFile(p, raw, 'utf8')
78
   fs.createFile(p, raw, 'utf8')
79
     .then(() => {
79
     .then(() => {
80
-      let stream = fs.readStream(p, 'utf8')
81
       let d = ''
80
       let d = ''
82
-      stream.onData((chunk) => {
83
-        d += chunk
84
-      })
85
-      stream.onEnd(() => {
86
-        report(<Assert key="utf8 content test"  expect={raw} actual={d}/>)
87
-        testBase64()
88
-      })
89
-    })
90
-  function testBase64() {
91
-    fs.createFile(p + '-base64', RNFetchBlob.base64.encode(raw), 'base64')
92
-      .then(() => {
93
-        let stream = fs.readStream(p + '-base64', 'utf8')
94
-        let d = ''
81
+      fs.readStream(p, 'utf8').then((stream) => {
82
+        stream.open()
95
         stream.onData((chunk) => {
83
         stream.onData((chunk) => {
96
           d += chunk
84
           d += chunk
97
         })
85
         })
98
         stream.onEnd(() => {
86
         stream.onEnd(() => {
99
-          report(<Assert
100
-            key="base64 content test"
101
-            expect={raw}
102
-            actual={d}/>)
103
-          // testASCII()
104
-          done()
87
+          report(<Assert key="utf8 content test"  expect={raw} actual={d}/>)
88
+          testBase64()
105
         })
89
         })
106
       })
90
       })
107
-      .catch((err) => {
108
-        console.log(err)
109
-      })
110
-  }
111
-  function testASCII() {
112
-    fs.createFile(p + '-ascii', raw, 'ascii')
91
+    })
92
+  function testBase64() {
93
+    fs.createFile(p + '-base64', RNFetchBlob.base64.encode(raw), 'base64')
113
       .then(() => {
94
       .then(() => {
114
-        let stream = fs.readStream(p + '-ascii', 'ascii')
115
-        let d = ''
116
-        stream.onData((chunk) => {
117
-          d += chunk
118
-        })
119
-        stream.onEnd(() => {
120
-          report(<Assert
121
-            key="ASCII content test"
122
-            expect={raw}
123
-            actual={d}/>)
124
-          done()
95
+        fs.readStream(p + '-base64', 'utf8').then((stream) => {
96
+            stream.open()
97
+            let d = ''
98
+            stream.onData((chunk) => {
99
+              d += chunk
100
+            })
101
+            stream.onEnd(() => {
102
+              report(<Assert
103
+                key="base64 content test"
104
+                expect={raw}
105
+                actual={d}/>)
106
+                done()
107
+              })
125
         })
108
         })
126
       })
109
       })
127
       .catch((err) => {
110
       .catch((err) => {
197
       return ws.close()
180
       return ws.close()
198
     })
181
     })
199
     .then(() => {
182
     .then(() => {
200
-      let rs = fs.readStream(p, 'utf8')
201
       let d1 = ''
183
       let d1 = ''
202
-      rs.onData((chunk) => {
203
-        d1 += chunk
204
-      })
205
-      rs.onEnd(() => {
206
-        report(
207
-          <Assert key="write data async test"
208
-            expect={'123456789011121314'}
209
-            actual={d1}/>)
210
-          base64Test()
184
+      fs.readStream(p, 'utf8').then((stream) => {
185
+        stream.open()
186
+        stream.onData((chunk) => {
187
+          d1 += chunk
188
+        })
189
+        stream.onEnd(() => {
190
+          report(
191
+            <Assert key="write data async test"
192
+              expect={'123456789011121314'}
193
+              actual={d1}/>)
194
+            base64Test()
195
+        })
211
       })
196
       })
212
     })
197
     })
213
   function base64Test() {
198
   function base64Test() {
220
       return ws.close()
205
       return ws.close()
221
     })
206
     })
222
     .then(() => {
207
     .then(() => {
223
-      let rs = fs.readStream(p, 'base64')
208
+      return fs.readStream(p, 'base64')
209
+    })
210
+    .then((stream) => {
224
       let d2 = ''
211
       let d2 = ''
225
-      rs.onData((chunk) => {
212
+      stream.open()
213
+      stream.onData((chunk) => {
226
         d2 += chunk
214
         d2 += chunk
227
       })
215
       })
228
-      rs.onEnd(() => {
216
+      stream.onEnd(() => {
229
         report(
217
         report(
230
           <Assert key="file should be overwritten by base64 encoded data"
218
           <Assert key="file should be overwritten by base64 encoded data"
231
             expect={RNFetchBlob.base64.encode(expect)}
219
             expect={RNFetchBlob.base64.encode(expect)}
254
   })
242
   })
255
   .then((files) => {
243
   .then((files) => {
256
     report(<Assert key="file name should be correct" expect={'moved'} actual={files[0]}/>)
244
     report(<Assert key="file name should be correct" expect={'moved'} actual={files[0]}/>)
257
-    let rs = fs.readStream(dest + '/moved')
258
-    let actual = ''
259
-    rs.onData((chunk) => {
260
-      actual += chunk
261
-    })
262
-    rs.onEnd(() => {
263
-      report(<Assert key="file content should be correct" expect={content} actual={actual}/>)
264
-      done()
245
+    fs.readStream(dest + '/moved').then((rs) => {
246
+      rs.open()
247
+      let actual = ''
248
+      rs.onData((chunk) => {
249
+        actual += chunk
250
+      })
251
+      rs.onEnd(() => {
252
+        report(<Assert key="file content should be correct" expect={content} actual={actual}/>)
253
+        done()
254
+      })
265
     })
255
     })
266
   })
256
   })
267
 })
257
 })
280
   })
270
   })
281
   .then((files) => {
271
   .then((files) => {
282
     report(<Assert key="file name should be correct" expect={'cp'} actual={files[0]}/>)
272
     report(<Assert key="file name should be correct" expect={'cp'} actual={files[0]}/>)
283
-    let rs = fs.readStream(dest + '/cp')
284
-    let actual = ''
285
-    rs.onData((chunk) => {
286
-      actual += chunk
287
-    })
288
-    rs.onEnd(() => {
289
-      report(<Assert key="file content should be correct" expect={content} actual={actual}/>)
290
-      done()
273
+    fs.readStream(dest + '/cp').then((rs) => {
274
+      rs.open()
275
+      let actual = ''
276
+      rs.onData((chunk) => {
277
+        actual += chunk
278
+      })
279
+      rs.onEnd(() => {
280
+        report(<Assert key="file content should be correct" expect={content} actual={actual}/>)
281
+        done()
282
+      })
291
     })
283
     })
292
   })
284
   })
293
 })
285
 })
304
       return fs.writeStream(p, 'ascii', false)
296
       return fs.writeStream(p, 'ascii', false)
305
     })
297
     })
306
     .then((ofstream) => {
298
     .then((ofstream) => {
307
-      let qq = []
308
       for(let i=0;i<expect.length;i++) {
299
       for(let i=0;i<expect.length;i++) {
309
-        qq.push(expect[i].charCodeAt(0))
310
         ofstream.write([expect[i].charCodeAt(0)])
300
         ofstream.write([expect[i].charCodeAt(0)])
311
       }
301
       }
312
       ofstream.write(['g'.charCodeAt(0), 'g'.charCodeAt(0)])
302
       ofstream.write(['g'.charCodeAt(0), 'g'.charCodeAt(0)])
313
       return ofstream.close()
303
       return ofstream.close()
314
     })
304
     })
315
     .then(() => {
305
     .then(() => {
316
-      let ifstream = fs.readStream(p, 'ascii')
317
-      let res = []
318
-      ifstream.onData((chunk) => {
319
-        res = res.concat(chunk)
320
-      })
321
-      ifstream.onEnd(() => {
322
-        res = res.map((byte) => {
323
-          return String.fromCharCode(byte)
324
-        }).join('')
325
-        report(
326
-          <Assert key="data written in ASCII format should correct"
327
-            expect={expect + 'gg'}
328
-            actual={res}
329
-          />)
330
-        done()
306
+      fs.readStream(p, 'ascii').then((ifstream) => {
307
+        let res = []
308
+        ifstream.open()
309
+        ifstream.onData((chunk) => {
310
+          res = res.concat(chunk)
311
+        })
312
+        ifstream.onEnd(() => {
313
+          res = res.map((byte) => {
314
+            return String.fromCharCode(byte)
315
+          }).join('')
316
+          report(
317
+            <Assert key="data written in ASCII format should correct"
318
+              expect={expect + 'gg'}
319
+              actual={res}
320
+            />)
321
+              done()
322
+            })
331
       })
323
       })
332
     })
324
     })
333
 })
325
 })
344
     return fs.createFile(p + filename, getASCIIArray(expect), 'ascii')
336
     return fs.createFile(p + filename, getASCIIArray(expect), 'ascii')
345
   })
337
   })
346
   .then(() => {
338
   .then(() => {
347
-    let rs = fs.readStream(p + filename, 'base64')
348
-    let actual = ''
349
-    rs.onData((chunk) => {
350
-      actual += chunk
339
+    fs.readStream(p + filename, 'base64').then((rs) => {
340
+      let actual = ''
341
+      rs.open()
342
+      rs.onData((chunk) => {
343
+        actual += chunk
344
+      })
345
+      rs.onEnd(() => {
346
+        report(<Assert key="written data verify"
347
+          expect={expect}
348
+          actual={base64.decode(actual)}/>)
349
+        done()
350
+      })
351
     })
351
     })
352
-    rs.onEnd(() => {
353
-      report(<Assert key="written data verify"
354
-        expect={expect}
355
-        actual={base64.decode(actual)}/>)
356
-      done()
352
+  })
353
+})
354
+
355
+describe('format conversion', (report, done) => {
356
+  let p = ''
357
+  fs.getSystemDirs().then((dirs) => {
358
+    p = dirs.DocumentDir + '/foo'
359
+    return fs.createFile(p, [102, 111, 111], 'ascii')
360
+  })
361
+  .then(() => {
362
+    fs.readStream(p, 'utf8').then((stream) => {
363
+      let res = []
364
+      stream.open()
365
+      stream.onData((chunk) => {
366
+        res+=chunk
367
+      })
368
+      stream.onEnd(() => {
369
+        report(
370
+          <Assert key="write utf8 and read by ascii"
371
+            expect="foo"
372
+            actual={res}/>)
373
+            done()
374
+      })
357
     })
375
     })
358
   })
376
   })
359
 })
377
 })