1# Saving User Files
2
3When a user needs to download a file from the Internet or save a file to another directory, use **FilePicker** to save the file. The permission on the file URI granted by Picker, however, is temporary. If required, you can persist the permission on the URI. For details, see [Persisting a Temporary Permission Granted by Picker](file-persistPermission.md#persisting-a-temporary-permission-granted-by-picker).
4
5The 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.
6
7Currently, all the **save()** behaviors of **FilePicker** can be perceived by users. Specifically, **FilePicker** is started to save the files to a directory managed by **FileManager**. The files are isolated from the assets managed by **Gallery** and cannot be viewed in **Gallery**.
8
9To enable the saved image or video to be viewed in **Gallery**, [create the media asset using a security component](../media/medialibrary/photoAccessHelper-savebutton.md).
10
11
12## Saving Images or Videos
13
14[PhotoViewPicker](../reference/apis-core-file-kit/js-apis-file-picker.md#photoviewpicker) will not be maintained in later versions. You are advised to [use a security component to create a media asset](../media/medialibrary/photoAccessHelper-savebutton.md).
15
16If the security component cannot be called to save images and videos in your development, use [PhotoAccessHelper.showAssetsCreationDialog](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#showassetscreationdialog12) to save images and videos.
17
18## Saving Documents
19
201. Import modules.
21
22   ```ts
23   import { picker } from '@kit.CoreFileKit';
24   import { fileIo as fs } from '@kit.CoreFileKit';
25   import { BusinessError } from '@kit.BasicServicesKit';
26   import { common } from '@kit.AbilityKit';
27   ```
28
292. Create a **documentSaveOptions** instance.
30
31   ```ts
32   // Create a documentSaveOptions instance.
33   const documentSaveOptions = new picker.DocumentSaveOptions();
34   // (Optional) Name of the document to save.
35   documentSaveOptions.newFileNames = ["DocumentViewPicker01.txt"];
36   // (Optional) Type of the document to save. The value is in ['Description|File name extensions'] format. To save all documents, use 'All files (*.*)|.*'. If there are multiple file name extensions, the first one is used by default.
37   documentSaveOptions.fileSuffixChoices = ['Document|.txt', '.pdf'];
38   ```
39
403. Create a [DocumentViewPicker](../reference/apis-core-file-kit/js-apis-file-picker.md#constructor12) instance, and call [save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save) to start the FilePicker page to save the document.
41
42   ```ts
43   let uris: Array<string> = [];
44   // Ensure that getContext(this) returns UIAbilityContext.
45   let context = getContext(this) as common.Context;
46   // Create a DocumentViewPicker instance.
47   const documentViewPicker = new picker.DocumentViewPicker(context);
48   // After the user selects the target folder and saves the documents, the URIs of the saved documents are returned.
49   documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
50     uris = documentSaveResult;
51     console.info('documentViewPicker.save to file succeed and uris are:' + uris);
52   }).catch((err: BusinessError) => {
53     console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
54   })
55   ```
56
57> **NOTE**
58>
59> - Avoid directly using a URI in the Picker callback to open the document. Instead, define a global variable to save the URI.
60> - The permission for the URIs returned by [save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save) of Picker is a temporary read/write permission. The temporary permission will be invalidated once the application exits.
61> - You can persist the temporary permission for a URI, which is available only for 2-in-1 devices. For details, see [Persisting a Temporary Permission Granted by Picker](file-persistPermission.md#persisting-a-temporary-permission-granted-by-picker).
62> - You can also directly save the documents to the **Download** folder. For details, see [Saving Files to the Download Directory](#saving-files-to-the-download-directory).
63
644. After the application UI is returned from FilePicker, call [fs.openSync](../reference/apis-core-file-kit/js-apis-file-fs.md#fsopensync) to open a document based on the URI. The file descriptor (FD) is returned after the document is opened.
65
66   ```ts
67   const uri = '';
68   // Note that the permission specified by the mode parameter of fs.openSync() is fs.OpenMode.READ_WRITE.
69   let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
70   console.info('file fd: ' + file.fd);
71   ```
72
735. Call [fs.writeSync](../reference/apis-core-file-kit/js-apis-file-fs.md#writesync) to modify the document based on the FD, and call **fs.closeSync()** to close the FD.
74
75   ```ts
76   let writeLen: number = fs.writeSync(file.fd, 'hello, world');
77   console.info('write data to file succeed and size is:' + writeLen);
78   fs.closeSync(file);
79   ```
80
81## Saving Audio Clips
82
831. Import modules.
84
85   ```ts
86   import { picker } from '@kit.CoreFileKit';
87   import { fileIo as fs } from '@kit.CoreFileKit';
88   import { BusinessError } from '@kit.BasicServicesKit';
89   import { common } from '@kit.AbilityKit';
90   ```
91
922. Create an **audioSaveOptions** instance.
93
94   ```ts
95   // Create an audioSaveOptions instance.
96   const audioSaveOptions = new picker.AudioSaveOptions();
97   // Set the name of the audio clip to save. This parameter is optional.
98   audioSaveOptions.newFileNames = ['AudioViewPicker01.mp3'];
99   ```
100
1013. Create an [AudioViewPicker](../reference/apis-core-file-kit/js-apis-file-picker.md#audioviewpicker) instance and use [save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save-5) to start the FilePicker page to save the audio clip.
102   ```ts
103   let uri: string = '';
104   // Ensure that getContext(this) returns UIAbilityContext.
105   let context = getContext(this) as common.Context;
106   const audioViewPicker = new picker.AudioViewPicker(context);
107   // After the user selects the target folder and saves the audio clips, the URIs of the saved audio clips are returned.
108   audioViewPicker.save(audioSaveOptions).then((audioSelectResult: Array<string>) => {
109     uri = audioSelectResult[0];
110     console.info('audioViewPicker.save to file succeed and uri is:' + uri);
111   }).catch((err: BusinessError) => {
112     console.error(`Invoke audioViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
113   })
114   ```
115> **NOTE**
116>
117> - Avoid directly using a URI in the Picker callback to open the audio clip. Instead, define a global variable to save the URI.
118> - The permission for the URIs returned by [save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save-3) of Picker is a temporary read/write permission. The temporary permission will be invalidated once the application exits.
119> - You can persist the temporary permission for a URI, which is available only for 2-in-1 devices. For details, see [Persisting a Temporary Permission Granted by Picker](file-persistPermission.md#persisting-a-temporary-permission-granted-by-picker).
120> - You can also directly save audio clips to the **Download** folder. For details, see [Saving Files to the Download Directory](#saving-files-to-the-download-directory).
121
1224. After the application UI is returned from FilePicker, call [fs.openSync](../reference/apis-core-file-kit/js-apis-file-fs.md#fsopensync) to open an audio clip based on the URI. The FD is returned after the audio clip is opened.
123
124   ```ts
125   // Note that the permission specified by the mode parameter of fs.openSync() is fileIo.OpenMode.READ_WRITE.
126   let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
127   console.info('file fd: ' + file.fd);
128   ```
129
1305. Call [fs.writeSync](../reference/apis-core-file-kit/js-apis-file-fs.md#writesync) to modify the audio clip based on the FD, and use **fs.closeSync()** to close the FD.
131
132   ```ts
133   let writeLen = fs.writeSync(file.fd, 'hello, world');
134   console.info('write data to file succeed and size is:' + writeLen);
135   fs.closeSync(file);
136
137   ```
138## Saving Files to the Download Directory
139
140When using **save()**, you can set **pickerMode** to **DOWNLOAD**, which will trigger user authorization. After the user allows the operation, a folder with the current HAP bundle name will be created in the **Download** directory of the user, and the folder URI will be returned by **save()**. As a result, user files can be directly stored in the folder with this URI.
1411. Import modules.
142
143   ```ts
144   import { picker } from '@kit.CoreFileKit';
145   import { fileIo as fs } from '@kit.CoreFileKit';
146   import { BusinessError } from '@kit.BasicServicesKit';
147   import { common } from '@kit.AbilityKit';
148   ```
149
1502. Create a **documentSaveOptions** instance.
151
152   ```ts
153   // Create a documentSaveOptions instance.
154   const documentSaveOptions = new picker.DocumentSaveOptions();
155   // Set pickerMode to DOWNLOAD, which takes precedence over the settings in documentSaveOptions.
156   documentSaveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD;
157   ```
158
1593. Create a **DocumentViewPicker** instance, and call [save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save-1) to start the FilePicker modal page to save the audio clip. After the user allows the operation, a folder of the corresponding application is created in the **Download** directory and the URI of the folder is returned.
160
161   ```ts
162   let uri: string = '';
163   // Ensure that getContext(this) returns UIAbilityContext.
164   let context = getContext(this) as common.Context;
165   const documentViewPicker = new picker.DocumentViewPicker(context);
166   const documentSaveOptions = new picker.DocumentSaveOptions();
167   documentSaveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD;
168   documentViewPicker.save(documentSaveOptions ).then((documentSaveResult: Array<string>) => {
169     uri = documentSaveResult[0];
170     console.info('documentViewPicker.save succeed and uri is:' + uri);
171   }).catch((err: BusinessError) => {
172     console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
173   })
174   ```
175