• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 获取并使用公共目录
2
3## 通过 ArkTS 接口获取并访问公共目录
4
5目录环境能力接口([ohos.file.environment](../reference/apis-core-file-kit/js-apis-file-environment.md))提供获取公共目录路径的能力,支持三方应用在公共文件用户目录下进行文件访问操作。
6
7 **约束限制**
8 - 使用此方式,需确认设备具有以下系统能力:SystemCapability.FileManagement.File.Environment.FolderObtain,当前仅支持2in1设备。
9   ```ts
10   if (!canIUse('SystemCapability.FileManagement.File.Environment.FolderObtain')) {
11       console.error('this api is not supported on this device');
12       return;
13   }
14   ```
15 - 公共目录获取接口仅用于获取公共目录路径,不对公共目录访问权限进行校验。若需访问公共目录需申请对应的公共目录访问权限。三方应用需要访问公共目录时,需通过弹窗授权向用户申请授予 Download 目录权限、Documents 目录权限或 Desktop 目录权限,具体参考[访问控制-向用户申请授权](../security/AccessToken/request-user-authorization.md)。
16   <!--RP1-->
17   ```json
18   "requestPermissions" : [
19       "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY",
20       "ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY",
21       "ohos.permission.READ_WRITE_DESKTOP_DIRECTORY",
22   ]
23   ```
24   <!--RP1End-->
25
26### 示例
27
281. 获取公共目录路径。
29
30   ```ts
31    import { BusinessError } from '@kit.BasicServicesKit';
32    import { Environment } from '@kit.CoreFileKit';
33
34    function getUserDirExample() {
35        try {
36            const downloadPath = Environment.getUserDownloadDir();
37            console.info(`success to getUserDownloadDir: ${downloadPath}`);
38            const documentsPath = Environment.getUserDocumentDir();
39            console.info(`success to getUserDocumentDir: ${documentsPath}`);
40        } catch (error) {
41            const err: BusinessError = error as BusinessError;
42            console.error(`failed to get user dir, because: ${JSON.stringify(err)}`);
43        }
44    }
45   ```
46
472. 以 Download 目录为例,访问 Download 目录下的文件。
48
49   ```ts
50    import { BusinessError } from '@kit.BasicServicesKit';
51    import { Environment } from '@kit.CoreFileKit';
52    import { fileIo as fs } from '@kit.CoreFileKit';
53    import { common } from '@kit.AbilityKit';
54
55    // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
56    let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
57
58    function readUserDownloadDirExample(context: common.UIAbilityContext) {
59        // 检查是否具有 READ_WRITE_DOWNLOAD_DIRECTORY 权限,无权限则需要向用户申请授予权限。
60        try {
61            // 获取 Download 目录
62            const downloadPath = Environment.getUserDownloadDir();
63            console.info(`success to getUserDownloadDir: ${downloadPath}`);
64            const dirPath = context.filesDir;
65            console.info(`success to get filesDir: ${dirPath}`);
66            // 查看 Download 目录下的文件并拷贝到沙箱目录中
67            let fileList: string[] = fs.listFileSync(downloadPath);
68            fileList.forEach((file, index) => {
69                console.info(`${downloadPath} ${index}: ${file}`);
70                fs.copyFileSync(`${downloadPath}/${file}`, `${dirPath}/${file}`);
71            });
72            // 查看沙箱目录下对应的文件
73            fileList = fs.listFileSync(dirPath);
74            fileList.forEach((file, index) => {
75                console.info(`${dirPath} ${index}: ${file}`);
76            });
77        } catch (error) {
78            const err: BusinessError = error as BusinessError;
79            console.error(`Error code: ${err.code}, message: ${err.message}`);
80        }
81    }
82   ```
83
843. 以 Download 目录为例,保存文件到 Download 目录。
85
86   ```ts
87    import { BusinessError } from '@kit.BasicServicesKit';
88    import { Environment } from '@kit.CoreFileKit';
89    import { fileIo as fs } from '@kit.CoreFileKit';
90
91    function writeUserDownloadDirExample() {
92    // 检查是否具有 READ_WRITE_DOWNLOAD_DIRECTORY 权限,无权限则需要向用户申请授予权限。
93        try {
94            // 获取 Download 目录
95            const downloadPath = Environment.getUserDownloadDir();
96            console.info(`success to getUserDownloadDir: ${downloadPath}`);
97            // 保存 temp.txt 到 Download 目录下
98            const file = fs.openSync(`${downloadPath}/temp.txt`, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
99            fs.writeSync(file.fd, 'write a message');
100            fs.closeSync(file);
101        } catch (error) {
102            const err: BusinessError = error as BusinessError;
103            console.error(`Error code: ${err.code}, message: ${err.message}`);
104        }
105    }
106   ```
107
108
109
110## 通过 C/C++ 接口获取并使用公共目录
111
112除了通过 ArkTS 访问公共目录的方式,也可通过 C/C++ 接口进行目录访问,具体可以参考 [Environment](../reference/apis-core-file-kit/_environment.md)。
113
114 **约束限制**
115 - 使用此接口,需确认设备具有以下系统能力:SystemCapability.FileManagement.File.Environment.FolderObtain116 - 三方应用需要访问公共目录时,需通过弹窗授权向用户申请授予 Download 目录权限、Documents 目录权限或 Desktop 目录权限,具体参考[访问控制-向用户申请授权](../security/AccessToken/request-user-authorization.md)。
117
118### 接口说明
119
120接口的详细说明,请参考[API参考](../reference/apis-core-file-kit/_environment.md)。
121
122| 接口名称                                                                 | 描述                           |
123| ------------------------------------------------------------------------ | ------------------------------ |
124| FileManagement_ErrCode OH_Environment_GetUserDownloadDir (char **result) | 获取用户Download目录沙箱路径。只支持2in1设备 |
125| FileManagement_ErrCode OH_Environment_GetUserDesktopDir (char **result)  | 获取用户Desktop目录沙箱路径。只支持2in1设备  |
126| FileManagement_ErrCode OH_Environment_GetUserDocumentDir (char **result) | 获取用户Document目录沙箱路径。只支持2in1设备 |
127
128### 开发步骤
129
130**在CMake脚本中链接动态库**
131
132CMakeLists.txt中添加以下lib。
133
134```txt
135target_link_libraries(sample PUBLIC libohenvironment.so libhilog_ndk.z.so)
136```
137
138**添加头文件**
139
140```c++
141#include <filemanagement/environment/oh_environment.h>
142#include <filemanagement/fileio/oh_fileio.h>
143#include <hilog/log.h>
144```
145
1461. 调用 OH_Environment_GetUserDownloadDir 接口获取用户 Download 目录沙箱路径,在接口中使用malloc申请的内存需要在使用完后释放因此需要free对应的内存。示例代码如下所示:
147
148    ```c++
149    void GetUserDownloadDirExample()
150    {
151        char *downloadPath = nullptr;
152        FileManagement_ErrCode ret = OH_Environment_GetUserDownloadDir(&downloadPath);
153        if (ret == 0) {
154            OH_LOG_INFO(LOG_APP, "Download Path=%{public}s", downloadPath);
155            free(downloadPath);
156        } else {
157            OH_LOG_ERROR(LOG_APP, "GetDownloadPath fail, error code is %{public}d", ret);
158        }
159    }
160    ```
161
1622. 调用 OH_Environment_GetUserDownloadDir 接口获取用户 Download 目录沙箱路径,并查看 Download 目录下的文件。示例代码如下所示:
163
164    ```c++
165    void ScanUserDownloadDirPathExample()
166    {
167        // 获取 download 路径
168        char *downloadPath = nullptr;
169        FileManagement_ErrCode ret = OH_Environment_GetUserDownloadDir(&downloadPath);
170        if (ret == 0) {
171            OH_LOG_INFO(LOG_APP, "Download Path=%{public}s", downloadPath);
172        } else {
173            OH_LOG_ERROR(LOG_APP, "GetDownloadPath fail, error code is %{public}d", ret);
174            return;
175        }
176        // 查看文件夹下的文件
177        struct dirent **namelist = {nullptr};
178        int num = scandir(downloadPath, &namelist, nullptr, nullptr);
179        if (num < 0) {
180            free(downloadPath);
181            OH_LOG_ERROR(LOG_APP, "Failed to scan dir");
182            return;
183        }
184        for (int i = 0; i < num; i++) {
185            OH_LOG_INFO(LOG_APP, "%{public}s", namelist[i]->d_name);
186        }
187        free(downloadPath);
188        free(namelist);
189    }
190    ```
191
1923. 调用 OH_Environment_GetUserDownloadDir 接口获取用户 Download 目录沙箱路径,并保存 temp.txt 到 Download 目录下。示例代码如下所示:
193
194    ```c++
195    void WriteUserDownloadDirPathExample()
196    {
197        // 获取 download 路径
198        char *downloadPath = nullptr;
199        FileManagement_ErrCode ret = OH_Environment_GetUserDownloadDir(&downloadPath);
200        if (ret == 0) {
201            OH_LOG_INFO(LOG_APP, "Download Path=%{public}s", downloadPath);
202        } else {
203            OH_LOG_ERROR(LOG_APP, "GetDownloadPath fail, error code is %{public}d", ret);
204            return;
205        }
206        // 保存文件到 download 目录下
207        std::string filePath = std::string(downloadPath) + "/temp.txt";
208        free(downloadPath);
209
210        std::ofstream outfile;
211        outfile.open(filePath.c_str());
212        if (!outfile) {
213            OH_LOG_ERROR(LOG_APP, "Failed to open file");
214            return;
215        }
216        std::string msg = "Write a message";
217        outfile.write(msg.c_str(), sizeof(msg));
218        outfile.close();
219    }
220    ```
221