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