/*
* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { fileIo, fileUri } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { commonType } from '@kit.ArkData';
import { image } from '@kit.ImageKit';
import { MediaInfo, MediaType } from '../model/ContentInfo';
const DOMAIN = 0x0000;
const TAG = 'FileUtil';
const FORMAT = '%{public}s';
/*
* Select a picture from the gallery.
* @returns uri The uri for the selected file.
*/
export async function fileSelect(): Promise<Array<string>> {
let imgUri: Array<string> = [];
let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
photoSelectOptions.maxSelectNumber = 5;
let photoPicker = new photoAccessHelper.PhotoViewPicker();
try {
let photoSelectResult = await photoPicker.select(photoSelectOptions);
if (photoSelectResult && photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) {
imgUri = photoSelectResult.photoUris;
return imgUri;
} else {
return [];
}
} catch (error) {
hilog.error(DOMAIN, TAG, FORMAT, `PhotoViewPicker failed with err: ${error.code}, ${error.message}`);
return [];
}
}
// [Start write]
// [Start write_distributed_file]
export function writeDistributedFile(context: common.UIAbilityContext, displayName: string, mediaType: MediaType,
buf?: ArrayBuffer, uri?: string): void {
// The asset is written to the distributed file directory.
// Obtain the distributed file directory path.
let distributedDir: string = context.distributedFilesDir;
let fileName: string = '/' + displayName;
let filePath: string = distributedDir + fileName;
let file: fileIo.File | undefined = undefined;
let srcFile: fileIo.File | undefined = undefined;
try {
// Create a file in a distributed directory.
file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
hilog.info(DOMAIN, TAG, FORMAT, 'Create file success.');
if (mediaType === MediaType.MEDIA_IMAGE && buf) {
// Write content to a file (if the asset is a picture, the picture can be converted to a buffer to write)
fileIo.writeSync(file.fd, buf);
} else if (mediaType === MediaType.MEDIA_VIDEO && uri) {
srcFile = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
fileIo.copyFileSync(srcFile.fd, file.fd);
}
} catch (error) {
let err: BusinessError = error as BusinessError;
hilog.info(DOMAIN, TAG, FORMAT,
`Failed to openSync / writeSync / closeSync. Code: ${err.code}, message: ${err.message}`);
} finally {
// closed file.
if (file) {
fileIo.closeSync(file.fd);
}
if (srcFile) {
fileIo.closeSync(srcFile.fd);
}
}
}
// [End write]
// [End write_distributed_file]
// [Start fileCopy]
// [Start file_copy]
/*
* Copy distributed files.
* @param attachmentRecord
* @param key
*/
export function fileCopy(context: common.UIAbilityContext, attachment: commonType.Asset,
mediaUriArray: Array<MediaInfo>): void {
if (canIUse('SystemCapability.DistributedDataManager.CommonType')) {
let mediaName = attachment.name.substring(attachment.name.indexOf('_') + 1);
let mediaType = attachment.name.substring(0, attachment.name.indexOf('_'));
let filePath: string = context.distributedFilesDir + '/' + mediaName;
let savePath: string = context.filesDir + '/' + mediaName;
let file: fileIo.File | undefined = undefined;
let saveFile: fileIo.File | undefined = undefined;
let imageSourceApi: image.ImageSource | undefined;
try {
if (fileIo.accessSync(filePath)) {
saveFile = fileIo.openSync(savePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE);
let buf: ArrayBuffer = new ArrayBuffer(Number(attachment.size));
let readSize = 0;
let readLen = fileIo.readSync(file.fd, buf, {
offset: readSize
});
if (mediaType == MediaType.MEDIA_IMAGE) {
let sourceOptions: image.SourceOptions = {
sourceDensity: 120
};
imageSourceApi = image.createImageSource(buf, sourceOptions);
mediaUriArray.push({
imagePixelMap: imageSourceApi.createPixelMapSync(),
mediaName: mediaName,
mediaType: mediaType
});
} else if (mediaType == MediaType.MEDIA_VIDEO) {
mediaUriArray.push({
videoUri: attachment.uri,
mediaName: mediaName,
mediaType: mediaType
})
}
while (readLen > 0) {
readSize += readLen;
fileIo.writeSync(saveFile.fd, buf);
readLen = fileIo.readSync(file.fd, buf, {
offset: readSize
});
}
hilog.info(DOMAIN, TAG, FORMAT, `${attachment.name} synchronized successfully.`);
}
} catch (error) {
let err: BusinessError = error as BusinessError;
hilog.error(DOMAIN, TAG, FORMAT, `${attachment.name} fileCopy failed with err: ${JSON.stringify(err)}`);
} finally {
if (file) {
fileIo.closeSync(file.fd);
}
if (saveFile) {
fileIo.closeSync(saveFile.fd);
}
if (imageSourceApi) {
imageSourceApi.release();
imageSourceApi = undefined;
}
}
}
}
// [End fileCopy]
// [End file_copy]
/*
* Obtain distributed file asset information.
* @param append
* @returns
*/
export function getAssetInfo(context: common.UIAbilityContext, append: MediaInfo): commonType.Asset {
let filePath = context.distributedFilesDir + '/' + append.mediaName;
let attachment: commonType.Asset;
try {
fileIo.statSync(filePath);
let uri: string = fileUri.getUriFromPath(filePath);
let stat = fileIo.statSync(filePath);
attachment = {
name: `${append.mediaType}_${append.mediaName}`,
uri: uri,
path: filePath,
createTime: stat.ctime.toString(),
modifyTime: stat.ctime.toString(),
size: stat.size.toString()
};
hilog.info(DOMAIN, TAG, FORMAT, `[getAssetInfo] attachments: ${JSON.stringify(attachment)}`);
} catch (err) {
hilog.error(DOMAIN, TAG, FORMAT, `StatSync failed. Cause code: ${err.code}, message: ${err.message}`);
}
return attachment!;
}