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
16## Saving Documents
17
181. Import modules.
19
20   ```ts
21   import { picker } from '@kit.CoreFileKit';
22   import { fileIo as fs } from '@kit.CoreFileKit';
23   import { BusinessError } from '@kit.BasicServicesKit';
24   import { common } from '@kit.AbilityKit';
25   ```
262. Create a **documentSaveOptions** instance.
27
28   ```ts
29   // Create a documentSaveOptions instance.
30   const documentSaveOptions = new picker.DocumentSaveOptions();
31   // (Optional) Name of the document to save.
32   documentSaveOptions.newFileNames = ["DocumentViewPicker01.txt"];
33   // (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.
34   documentSaveOptions.fileSuffixChoices = ['Document|.txt', '.pdf'];
35   ```
36
373. Create a [DocumentViewPicker](../reference/apis-core-file-kit/js-apis-file-picker.md#constructor12-2) instance, and use [save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save-3) to start the FilePicker page to save the document.
38   ```ts
39   let uris: Array<string> = [];
40   // Ensure that getContext(this) returns UIAbilityContext.
41   let context = getContext(this) as common.Context;
42   // Create a DocumentViewPicker instance.
43   const documentViewPicker = new picker.DocumentViewPicker(context);
44   // After the user selects the target folder and saves the documents, the URIs of the saved documents are returned.
45   documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
46     uris = documentSaveResult;
47     console.info('documentViewPicker.save to file succeed and uris are:' + uris);
48   }).catch((err: BusinessError) => {
49     console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
50   })
51   ```
52> **NOTE**
53>
54> - The URI cannot be directly used in the Picker callback to open the document. You need to define a global variable to save the URI.
55> - 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.
56> - 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).
57> - You can also directly save the documents to the **Download** folder. For details, see [Saving Files to Download](#saving-files-to-download).
58
594. After the application UI is returned from FilePicker, use [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.
60
61   ```ts 
62   const uri = '';
63   // Note that the permission specified by the mode parameter of fs.openSync() is fs.OpenMode.READ_WRITE.
64   let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
65   console.info('file fd: ' + file.fd);
66   ```
67
685. Use [fs.writeSync](../reference/apis-core-file-kit/js-apis-file-fs.md#writesync) to modify the document based on the FD, and use **fs.closeSync()** to close the FD.
69
70   ```ts
71   let writeLen: number = fs.writeSync(file.fd, 'hello, world');
72   console.info('write data to file succeed and size is:' + writeLen);
73   fs.closeSync(file);
74   ```
75
76## Saving Audio Clips
77
781. Import modules.
79
80   ```ts
81   import { picker } from '@kit.CoreFileKit';
82   import { fileIo as fs } from '@kit.CoreFileKit';
83   import { BusinessError } from '@kit.BasicServicesKit';
84   import { common } from '@kit.AbilityKit';
85   ```
86
872. Create an **audioSaveOptions** instance.
88
89   ```ts
90   // Create an audioSaveOptions instance.
91   const audioSaveOptions = new picker.AudioSaveOptions();
92   // Set the name of the audio clip to save. This parameter is optional.
93   audioSaveOptions.newFileNames = ['AudioViewPicker01.mp3']; 
94   ```
95
963. 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-6) to start the FilePicker page to save the audio clip.
97   ```ts
98   let uri: string = '';
99   // Ensure that getContext(this) returns UIAbilityContext.
100   let context = getContext(this) as common.Context; 
101   const audioViewPicker = new picker.AudioViewPicker(context);
102   // After the user selects the target folder and saves the audio clips, the URIs of the saved audio clips are returned.
103   audioViewPicker.save(audioSaveOptions).then((audioSelectResult: Array<string>) => {
104     uri = audioSelectResult[0];
105     console.info('audioViewPicker.save to file succeed and uri is:' + uri);
106   }).catch((err: BusinessError) => {
107     console.error(`Invoke audioViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
108   })
109   ```
110> **NOTE**
111>
112> - The URI cannot be directly used in the Picker callback to open the audio clip. You need to define a global variable to save the URI.
113> - 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.
114> - 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).
115> - You can also directly save audio clips to the **Download** folder. For details, see [Saving Files to Download](#saving-files-to-download).
116
1174. After the application UI is returned from FilePicker, use [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.
118
119   ```ts
120   // Note that the permission specified by the mode parameter of fs.openSync() is fileIo.OpenMode.READ_WRITE.
121   let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
122   console.info('file fd: ' + file.fd);
123   ```
124
1255. Use [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.
126
127   ```ts
128   let writeLen = fs.writeSync(file.fd, 'hello, world');
129   console.info('write data to file succeed and size is:' + writeLen);
130   fs.closeSync(file);
131 
132   ```
133## Saving Files to Download
134
135When 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.
1361. Import modules.
137
138   ```ts
139   import { picker } from '@kit.CoreFileKit';
140   import { fileIo as fs } from '@kit.CoreFileKit';
141   import { BusinessError } from '@kit.BasicServicesKit';
142   import { common } from '@kit.AbilityKit';
143   ```
144
1452. Create a **documentSaveOptions** instance.
146
147   ```ts
148   // Create a documentSaveOptions instance.
149   const documentSaveOptions = new picker.DocumentSaveOptions();
150   // Set pickerMode to DOWNLOAD, which takes precedence over the settings in documentSaveOptions.
151   documentSaveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD; 
152   ```
153
1543. Create a **DocumentViewPicker** instance, and use [save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save-6) 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.
155   
156   ```ts
157   let uri: string = '';
158   // Ensure that getContext(this) returns UIAbilityContext.
159   let context = getContext(this) as common.Context; 
160   const documentViewPicker = new picker.DocumentViewPicker(context);
161   const documentSaveOptions = new picker.DocumentSaveOptions();
162   documentSaveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD;
163   documentViewPicker.save(documentSaveOptions ).then((documentSaveResult: Array<string>) => {
164     uri = documentSaveResult[0];
165     console.info('documentViewPicker.save succeed and uri is:' + uri);
166   }).catch((err: BusinessError) => {
167     console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
168   })
169   ```
170