save-user-file.md 10.1 KB
Newer Older
A
Annie_wang 已提交
1 2 3 4
# Saving User Files

When a user needs to download a file from the network to a local directory or save a user file into another directory, use **FilePicker** to save the file.

A
Annie_wang 已提交
5
The operations for saving images, audio or video clips, and documents are similar. Call **save()** of the corresponding picker instance and pass in **saveOptions**. No permission is required if your application uses **FilePicker** to access files.
A
Annie_wang 已提交
6

A
Annie_wang 已提交
7
The **save()** method saves files in the file manager, not in **Gallery**.
A
Annie_wang 已提交
8

A
Annie_wang 已提交
9 10 11

## Saving Images or Video Files

A
Annie_wang 已提交
12 13
For example, select an image from **Gallery** and save it to the file manager.

A
Annie_wang 已提交
14
1. Import the [picker](../reference/apis/js-apis-file-picker.md), [fs](../reference/apis/js-apis-file-fs.md), [photoAccessHelper](../reference/apis/js-apis-photoAccessHelper.md), and [dataSharePredicates](../reference/apis/js-apis-data-dataSharePredicates.md) modules.
A
Annie_wang 已提交
15 16 17

   ```ts
   import picker from '@ohos.file.picker';
A
Annie_wang 已提交
18
   import fs from '@ohos.file.fs';
A
Annie_wang 已提交
19 20
   import photoAccessHelper from '@ohos.file.photoAccessHelper';
   import dataSharePredicates from '@ohos.data.dataSharePredicates';
A
Annie_wang 已提交
21 22 23
   import common from '@ohos.app.ability.common';
   import image from '@ohos.multimedia.image';
   import { BusinessError } from '@ohos.base';
A
Annie_wang 已提交
24 25
   ```

A
Annie_wang 已提交
26
2. Obtain the thumbnail of the first image on the device. Before performing this operation, ensure that at least one image exists on the device.
A
Annie_wang 已提交
27 28

   ```ts
A
Annie_wang 已提交
29 30
   let context = getContext(this) as common.UIAbilityContext;
   let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
A
Annie_wang 已提交
31

A
Annie_wang 已提交
32 33
   let pixelmapArrayBuffer: ArrayBuffer;
   async function getPixelmap() {
A
Annie_wang 已提交
34 35
      try {
         let predicates = new dataSharePredicates.DataSharePredicates();
A
Annie_wang 已提交
36
         let fetchOption: photoAccessHelper.FetchOptions = {
A
Annie_wang 已提交
37 38 39
            fetchColumns: [],
            predicates: predicates
         };
A
Annie_wang 已提交
40
         let fetchResult = await phAccessHelper.getAssets(fetchOption);
A
Annie_wang 已提交
41 42 43
         console.info('[picker] getThumbnail fetchResult: ' + fetchResult);
         const asset = await fetchResult.getFirstObject();
         console.info('[picker] getThumbnail asset displayName = ', asset.displayName);
A
Annie_wang 已提交
44
         asset.getThumbnail().then((pixelMap: image.PixelMap) => {
A
Annie_wang 已提交
45 46 47 48 49
            let pixelBytesNumber = pixelMap.getPixelBytesNumber();
            const readBuffer = new ArrayBuffer(pixelBytesNumber);
            pixelMap.readPixelsToBuffer(readBuffer).then(() => {
               pixelmapArrayBuffer = readBuffer;
            })
A
Annie_wang 已提交
50 51
         }).catch((err: BusinessError) => {
            console.error('[picker] getThumbnail failed with error: ' + JSON.stringify(err));
A
Annie_wang 已提交
52 53
         });
      } catch (error) {
A
Annie_wang 已提交
54 55
         let err: BusinessError = error as BusinessError;
         console.error('[picker] getThumbnail error = ' + JSON.stringify(err));
A
Annie_wang 已提交
56 57
      }
   }
A
Annie_wang 已提交
58 59
   ```

A
Annie_wang 已提交
60
3. Create a **photoViewPicker** instance and call [save()](../reference/apis/js-apis-file-picker.md#save) to open the **FilePicker** page to save the image. After the user selects the destination folder, the image is saved and the URI of the saved image is returned.
A
Annie_wang 已提交
61
   
A
Annie_wang 已提交
62
   The permission on the URI returned by **save()** is read/write. Further operations on the file can be performed based on the URI in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
A
Annie_wang 已提交
63 64

   ```ts  
A
Annie_wang 已提交
65 66
   let uris: Array<string>;
   async function photoViewPickerSave() {
A
Annie_wang 已提交
67 68 69 70 71 72 73 74
      try {
         const photoSaveOptions = new picker.PhotoSaveOptions(); // Create a photoSaveOptions instance.
         photoSaveOptions.newFileNames = ["PhotoViewPicker01.png"]; // (Optional) Name of the file to be saved. The file name in the square brackets can be customized and must be unique. If the file name already exists on the device, change the file name. Otherwise, an error will be returned.

         const photoViewPicker = new picker.PhotoViewPicker();
         try {
            let photoSaveResult = await photoViewPicker.save(photoSaveOptions);
            if (photoSaveResult != undefined) {
A
Annie_wang 已提交
75 76
               uris = photoSaveResult;
               console.info('photoViewPicker.save to file succeed and uris are:' + uris);
A
Annie_wang 已提交
77
            }
A
Annie_wang 已提交
78 79
         } catch (error) {
            let err: BusinessError = error as BusinessError;
A
Annie_wang 已提交
80 81 82
            console.error(`[picker] Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
         }
      } catch (error) {
A
Annie_wang 已提交
83 84
         let err: BusinessError = error as BusinessError;
         console.info("[picker] photoViewPickerSave error = " + JSON.stringify(err));
A
Annie_wang 已提交
85 86
      }
   }
A
Annie_wang 已提交
87 88
   ```

A
Annie_wang 已提交
89
4. After the UI is returned from the **FilePicker** page, use a button to trigger API calling. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**.
A
Annie_wang 已提交
90

A
Annie_wang 已提交
91
   Then, use [fs.write](../reference/apis/js-apis-file-fs.md#fswrite) to modify the file based on the FD, and close the FD after the modification is complete.
A
Annie_wang 已提交
92 93

   ```ts
A
Annie_wang 已提交
94
   async function writeOnly(uri: string) {
A
Annie_wang 已提交
95 96 97 98 99 100
      try {
         let file = fs.openSync(uri, fs.OpenMode.WRITE_ONLY);
         let writeLen = await fs.write(file.fd, pixelmapArrayBuffer);
         fs.closeSync(file);
         console.info("[picker] writeOnly writeLen = " + writeLen);
      } catch (error) {
A
Annie_wang 已提交
101 102
         let err: BusinessError = error as BusinessError;
         console.info("[picker] writeOnly error: " + JSON.stringify(err));
A
Annie_wang 已提交
103 104
      }
   }
A
Annie_wang 已提交
105 106 107 108
   ```

## Saving Documents

A
Annie_wang 已提交
109
1. Import the **picker** and **fs** modules.
A
Annie_wang 已提交
110 111 112

   ```ts
   import picker from '@ohos.file.picker';
A
Annie_wang 已提交
113
   import fs from '@ohos.file.fs';
A
Annie_wang 已提交
114
   import { BusinessError } from '@ohos.base';
A
Annie_wang 已提交
115 116 117 118 119 120
   ```

2. Create a **documentSaveOptions** instance.

   ```ts
   const documentSaveOptions = new picker.DocumentSaveOptions(); // Create a documentSaveOptions instance.
A
Annie_wang 已提交
121
   documentSaveOptions.newFileNames = ["DocumentViewPicker01.txt"]; // (Optional) Set the name of the document to save.
A
Annie_wang 已提交
122
   documentSaveOptions.fileSuffixChoices = ['.png', '.txt', '.mp4']; // (Optional) Types of the documents to save.
A
Annie_wang 已提交
123 124
   ```

A
Annie_wang 已提交
125
3. Create a **documentViewPicker** instance, and call [save()](../reference/apis/js-apis-file-picker.md#save-3) to open the **FilePicker** page to save the document. After the user selects the destination folder, the document is saved and the URI of the document saved is returned.
A
Annie_wang 已提交
126
   
A
Annie_wang 已提交
127
   The permission on the URI returned by **save()** is read/write. Further operations on the file can be performed based on the URI in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
A
Annie_wang 已提交
128 129

   ```ts
A
Annie_wang 已提交
130
   let uris: Array<string>;
A
Annie_wang 已提交
131
   const documentViewPicker = new picker.DocumentViewPicker(); // Create a documentViewPicker instance.
A
Annie_wang 已提交
132 133 134 135
   documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
     uris = documentSaveResult;
     console.info('documentViewPicker.save to file succeed and uris are:' + uris);
   }).catch((err: BusinessError) => {
A
Annie_wang 已提交
136 137 138 139
     console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
   })
   ```

A
Annie_wang 已提交
140
4. After the UI is returned from the **FilePicker** page, use a button to trigger API calling. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**.
A
Annie_wang 已提交
141 142

   ```ts
A
Annie_wang 已提交
143
   let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
A
Annie_wang 已提交
144 145 146
   console.info('file fd: ' + file.fd);
   ```

A
Annie_wang 已提交
147
5. Use [fs.writeSync()](../reference/apis/js-apis-file-fs.md#writesync) to edit the document based on the FD, and then close the FD.
A
Annie_wang 已提交
148 149 150 151 152

   ```ts
   let writeLen = fs.writeSync(file.fd, 'hello, world');
   console.info('write data to file succeed and size is:' + writeLen);
   fs.closeSync(file);
A
Annie_wang 已提交
153 154 155 156
   ```

## Saving Audio Files

A
Annie_wang 已提交
157
1. Import the **picker** and **fs** modules.
A
Annie_wang 已提交
158 159 160

   ```ts
   import picker from '@ohos.file.picker';
A
Annie_wang 已提交
161
   import fs from '@ohos.file.fs';
A
Annie_wang 已提交
162
   import { BusinessError } from '@ohos.base';
A
Annie_wang 已提交
163 164 165 166 167 168
   ```

2. Create an **audioSaveOptions** instance.

   ```ts
   const audioSaveOptions = new picker.AudioSaveOptions(); // Create an audioSaveOptions instance.
A
Annie_wang 已提交
169
   audioSaveOptions.newFileNames = ['AudioViewPicker01.mp3']; // (Optional) Set the name of the audio file to save.
A
Annie_wang 已提交
170 171
   ```

A
Annie_wang 已提交
172
3. Create an **audioViewPicker** instance, and call [save()](../reference/apis/js-apis-file-picker.md#save-6) to open the **FilePicker** page to save the file. After the user selects the destination folder, the audio file is saved and the URI of the document saved is returned.
A
Annie_wang 已提交
173
   
A
Annie_wang 已提交
174
   The permission on the URI returned by **save()** is read/write. Further operations on the file can be performed based on the URI in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
A
Annie_wang 已提交
175
   
A
Annie_wang 已提交
176
   ```ts
A
Annie_wang 已提交
177
   let uri: string;
A
Annie_wang 已提交
178
   const audioViewPicker = new picker.AudioViewPicker();
A
Annie_wang 已提交
179
   audioViewPicker.save(audioSaveOptions).then((audioSelectResult: Array<string>) => {
A
Annie_wang 已提交
180 181
     uri = audioSelectResult[0];
     console.info('audioViewPicker.save to file succeed and uri is:' + uri);
A
Annie_wang 已提交
182
   }).catch((err: BusinessError) => {
A
Annie_wang 已提交
183 184 185 186
     console.error(`Invoke audioViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
   })
   ```

A
Annie_wang 已提交
187
4. After the UI is returned from the **FilePicker** page, use a button to trigger API calling. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**.
A
Annie_wang 已提交
188 189

   ```ts
A
Annie_wang 已提交
190
   let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
A
Annie_wang 已提交
191 192 193
   console.info('file fd: ' + file.fd);
   ```

A
Annie_wang 已提交
194
5. Use [fs.writeSync()](../reference/apis/js-apis-file-fs.md#writesync) to edit the document based on the FD, and then close the FD.
A
Annie_wang 已提交
195 196 197 198 199

   ```ts
   let writeLen = fs.writeSync(file.fd, 'hello, world');
   console.info('write data to file succeed and size is:' + writeLen);
   fs.closeSync(file);
A
Annie_wang 已提交
200
   ```
A
Annie_wang 已提交
201