
鸿蒙5文件操作:沙盒机制与安全访问实践
在鸿蒙5应用开发中,文件系统访问遵循严格的沙盒机制,确保应用数据的安全性和隐私性。本文将深入解析鸿蒙5的文件沙盒机制,并提供实际代码示例展示如何安全地进行文件操作。
一、鸿蒙5文件沙盒机制概述
鸿蒙5的文件系统访问具有以下特点:
应用沙盒隔离:每个应用有独立的文件存储空间
分级目录访问:不同目录有不同的访问权限
最小权限原则:应用只能访问明确申请的资源
媒体文件特殊处理:通过媒体库API访问共享媒体文件
二、文件目录结构
鸿蒙应用可以访问的主要目录:
目录类型 路径示例 访问方式 存储内容
应用安装目录 /data/storage/el1/bundle/ 只读 应用安装文件
应用沙盒目录 /data/storage/el2/ 读写 应用私有文件
用户文件目录 /data/storage/el1/base/ 读写 用户文件
缓存目录 /data/storage/el3/ 读写 临时缓存文件
媒体库目录 /media/ 需权限 共享媒体文件
三、基础文件操作实战
- 获取应用文件路径
import fileIO from ‘@ohos.fileio’
import fileuri from ‘@ohos.fileuri’
// 获取应用文件目录路径
function getAppFilesDir(): string {
const context = getContext(this)
return context.filesDir
}
// 获取应用缓存目录路径
function getAppCacheDir(): string {
const context = getContext(this)
return context.cacheDir
}
@Entry
@Component
struct FilePathDemo {
@State filesDir: string = ‘’
@State cacheDir: string = ‘’
aboutToAppear() {
this.filesDir = getAppFilesDir()
this.cacheDir = getAppCacheDir()
}
build() {
Column() {
Text(文件目录: ${this.filesDir}
)
Text(缓存目录: ${this.cacheDir}
)
}
}
}
2. 基本文件读写操作
// 写入文件
async function writeFile(filePath: string, content: string): Promise<void> {
const file = await fileIO.open(filePath, fileIO.OpenMode.READ_WRITE | fileIO.OpenMode.CREATE)
await fileIO.write(file.fd, content)
await fileIO.close(file.fd)
}
// 读取文件
async function readFile(filePath: string): Promise<string> {
const file = await fileIO.open(filePath, fileIO.OpenMode.READ_ONLY)
const stat = await fileIO.stat(filePath)
const buffer = new ArrayBuffer(stat.size)
await fileIO.read(file.fd, buffer)
await fileIO.close(file.fd)
return String.fromCharCode.apply(null, new Uint8Array(buffer))
}
// 示例使用
@Entry
@Component
struct FileIODemo {
@State fileContent: string = ‘’
@State inputText: string = ‘’
private filePath: string = ${getAppFilesDir()}/demo.txt
async saveContent() {
await writeFile(this.filePath, this.inputText)
this.fileContent = await readFile(this.filePath)
}
build() {
Column() {
TextInput({ placeholder: ‘输入要保存的内容’, text: this.inputText })
.onChange((value: string) => {
this.inputText = value
})
Button('保存文件')
.onClick(() => {
this.saveContent()
})
Text(`文件内容: ${this.fileContent}`)
}
}
}
四、沙盒机制下的安全访问
- 应用间文件共享
import abilityAccessCtrl from ‘@ohos.abilityAccessCtrl’
// 创建临时共享文件
async function createTempSharedFile(content: string): Promise<string> {
const tempDir = ${getAppFilesDir()}/temp/
await fileIO.mkdir(tempDir)
const tempFile = ${tempDir}shared_${Date.now()}.txt
await writeFile(tempFile, content)
// 转换为可共享的URI
return fileuri.getUriFromPath(tempFile)
}
// 示例:分享文件到其他应用
@Entry
@Component
struct FileShareDemo {
@State shareUri: string = ‘’
async shareFile() {
const uri = await createTempSharedFile(‘这是共享文件内容’)
this.shareUri = uri
try {
const want = {
action: 'ohos.want.action.sendData',
uri: uri,
type: 'text/plain'
}
await globalThis.abilityContext.startAbility(want)
} catch (err) {
console.error('分享失败:', err)
}
}
build() {
Column() {
Button(‘创建并分享文件’)
.onClick(() => {
this.shareFile()
})
Text(`文件URI: ${this.shareUri}`)
}
}
}
2. 媒体文件访问(需权限)
import mediaLibrary from ‘@ohos.multimedia.mediaLibrary’
// 获取媒体库实例
async function getMediaLibrary(): Promise<mediaLibrary.MediaLibrary> {
const context = getContext(this)
return mediaLibrary.getMediaLibrary(context)
}
// 保存图片到媒体库
async function saveImageToMediaLibrary(buffer: ArrayBuffer): Promise<string> {
const media = await getMediaLibrary()
const publicDir = mediaLibrary.DirectoryType.DIR_IMAGE
const date = new Date()
const name = IMG_${date.getFullYear()}${date.getMonth()+1}${date.getDate()}_${date.getTime()}.jpg
const fileAsset = await media.createAsset(
mediaLibrary.MediaType.IMAGE,
name,
publicDir
)
const fd = await fileAsset.open(‘rw’)
await fileIO.write(fd, buffer)
await fileAsset.close(fd)
return fileAsset.uri
}
// 从媒体库读取图片
async function getImagesFromMediaLibrary(): Promise<mediaLibrary.FileAsset[]> {
const media = await getMediaLibrary()
const fetchOp = {
selections: ${mediaLibrary.FileKey.MEDIA_TYPE}=?
,
selectionArgs: [mediaLibrary.MediaType.IMAGE.toString()],
order: ${mediaLibrary.FileKey.DATE_ADDED} DESC
}
return media.getFileAssets(fetchOp)
}
五、权限申请与管理
- 配置权限
在module.json5中添加所需权限:
{
“module”: {
“requestPermissions”: [
{
“name”: “ohos.permission.READ_MEDIA”,
“reason”: “读取媒体文件”
},
{
“name”: “ohos.permission.WRITE_MEDIA”,
“reason”: “保存媒体文件”
},
{
“name”: “ohos.permission.FILE_ACCESS_MANAGER”,
“reason”: “管理文件访问”
}
]
}
}
2. 动态权限申请
import abilityAccessCtrl from ‘@ohos.abilityAccessCtrl’
async function requestMediaPermissions(): Promise<boolean> {
const permissions: Array<string> = [
‘ohos.permission.READ_MEDIA’,
‘ohos.permission.WRITE_MEDIA’
]
const atManager = abilityAccessCtrl.createAtManager()
try {
const result = await atManager.requestPermissionsFromUser(permissions)
return result.authResults.every(granted => granted)
} catch (err) {
console.error(‘权限申请失败:’, err)
return false
}
}
// 使用示例
@Entry
@Component
struct PermissionDemo {
@State hasPermission: boolean = false
async checkPermissions() {
this.hasPermission = await requestMediaPermissions()
}
build() {
Column() {
Button(‘申请媒体文件权限’)
.onClick(() => {
this.checkPermissions()
})
Text(this.hasPermission ? '已获得权限' : '未获得权限')
}
}
}
六、安全最佳实践
敏感数据加密存储:对重要数据加密后再写入文件
及时清理临时文件:使用后删除临时共享文件
最小权限原则:只申请必要的文件访问权限
输入验证:处理外部传入的文件路径时进行严格验证
沙盒内存储:优先使用应用私有目录存储数据
七、加密文件操作示例
import cryptoFramework from ‘@ohos.security.cryptoFramework’
// 加密并保存文件
async function encryptAndSaveFile(path: string, content: string, key: string): Promise<void> {
// 生成对称密钥
const symKeyGenerator = cryptoFramework.createSymKeyGenerator(‘AES128’)
const keyBlob: cryptoFramework.DataBlob = { data: new Uint8Array(key.padEnd(16).slice(0,16)).buffer }
const symKey = await symKeyGenerator.convertKey(keyBlob)
// 创建加密器
const cipher = cryptoFramework.createCipher(‘AES128|ECB|PKCS7’)
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null)
// 加密数据
const plainBlob: cryptoFramework.DataBlob = { data: new TextEncoder().encode(content).buffer }
const cipherBlob = await cipher.doFinal(plainBlob)
// 保存加密后的文件
await writeFile(path, String.fromCharCode.apply(null, new Uint8Array(cipherBlob.data)))
}
// 解密文件
async function decryptFile(path: string, key: string): Promise<string> {
// 读取加密文件
const encryptedData = await readFile(path)
const encryptedBuffer = new Uint8Array(encryptedData.split(‘’).map(c => c.charCodeAt(0))).buffer
// 生成对称密钥
const symKeyGenerator = cryptoFramework.createSymKeyGenerator(‘AES128’)
const keyBlob: cryptoFramework.DataBlob = { data: new Uint8Array(key.padEnd(16).slice(0,16)).buffer }
const symKey = await symKeyGenerator.convertKey(keyBlob)
// 创建解密器
const cipher = cryptoFramework.createCipher(‘AES128|ECB|PKCS7’)
await cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, null)
// 解密数据
const cipherBlob: cryptoFramework.DataBlob = { data: encryptedBuffer }
const plainBlob = await cipher.doFinal(cipherBlob)
return new TextDecoder().decode(plainBlob.data)
}
八、总结
鸿蒙5的文件沙盒机制通过以下方式保障数据安全:
严格隔离:应用文件系统相互隔离
权限控制:分级目录访问和运行时权限检查
安全共享:通过URI机制安全共享文件
加密支持:提供完善的加密API保护敏感数据
