199 lines
5.8 KiB
Plaintext
199 lines
5.8 KiB
Plaintext
// @ts-nocheck
|
||
export * from '../interface'
|
||
import type { ProcessFileOptions, NullableString } from '../interface'
|
||
import { fileIo } from '@kit.CoreFileKit';
|
||
// import { getRealPath } from '@dcloudio/uni-runtime'
|
||
import buffer from '@ohos.buffer';
|
||
import util from '@ohos.util';
|
||
import { getEnv } from '@dcloudio/uni-runtime';
|
||
// 常见MIME类型映射(可根据需求扩展)
|
||
const mimeTypeMap : Record<string, string> = {
|
||
// 图片类型
|
||
'jpg': 'image/jpeg',
|
||
'jpeg': 'image/jpeg',
|
||
'png': 'image/png',
|
||
'gif': 'image/gif',
|
||
'webp': 'image/webp',
|
||
'svg': 'image/svg+xml',
|
||
|
||
// 文本类型
|
||
'txt': 'text/plain',
|
||
'html': 'text/html',
|
||
'htm': 'text/html',
|
||
'css': 'text/css',
|
||
'csv': 'text/csv',
|
||
|
||
// 应用类型
|
||
'js': 'application/javascript',
|
||
'json': 'application/json',
|
||
'pdf': 'application/pdf',
|
||
'zip': 'application/zip',
|
||
'xml': 'application/xml',
|
||
|
||
// 音频类型
|
||
'mp3': 'audio/mpeg',
|
||
'wav': 'audio/wav',
|
||
|
||
// 视频类型
|
||
'mp4': 'video/mp4',
|
||
'mov': 'video/quicktime'
|
||
};
|
||
/**
|
||
* 检查路径存在性及类型 (Android 实现)
|
||
* @param path 要检查的完整路径(支持内部存储和外部存储路径)
|
||
* @return Pair<是否存在, 是否是目录>
|
||
*/
|
||
export function checkExistence(filePath : string) : boolean[] {
|
||
// const path = getRealPath(filePath)
|
||
const path = UTSHarmony.getResourcePath(filePath)
|
||
const exists = fileIo.accessSync(path)
|
||
const isDirectory = exists ? fileIo.statSync(path).isDirectory() : false;
|
||
return [exists, isDirectory]
|
||
}
|
||
|
||
/**
|
||
* 检查路径是否存在
|
||
* @param path 要检查的完整路径
|
||
*/
|
||
export function isExists(filePath : string) : boolean {
|
||
const result = checkExistence(filePath);
|
||
return result[0]
|
||
}
|
||
|
||
/**
|
||
* 检查路径是否是存在的目录
|
||
* @param path 要检查的完整路径
|
||
*/
|
||
export function isDirectory(filePath : string) : boolean {
|
||
const result = checkExistence(filePath);
|
||
return result[0] && result[1]
|
||
}
|
||
|
||
/**
|
||
* 检查指定路径是否为存在的文件
|
||
* @param path 要检查的完整路径
|
||
* @return 当且仅当路径存在且是普通文件时返回 true
|
||
*/
|
||
export function isFile(filePath : string) : boolean {
|
||
const result = checkExistence(filePath);
|
||
return result[0] && !result[1]
|
||
}
|
||
|
||
// 获取文件扩展名(自动处理大小写和特殊路径)
|
||
function getFileExtension(filePath : string) : string | null {
|
||
// 处理包含查询参数或哈希的路径(如网络路径)
|
||
const cleanPath = filePath.split(/[?#]/)[0];
|
||
const fileName = cleanPath.split('/').pop() || '';
|
||
const dotIndex = fileName.lastIndexOf('.');
|
||
|
||
if (dotIndex <= 0) return null; // 排除类似 ".hiddenfile" 的情况
|
||
return fileName.slice(dotIndex + 1).toLowerCase();
|
||
}
|
||
|
||
|
||
// 根据扩展名获取MIME类型
|
||
function getMimeType(extension : string | null) : string {
|
||
if (!extension) return 'application/octet-stream';
|
||
return mimeTypeMap[extension] || 'application/octet-stream';
|
||
}
|
||
|
||
export function fileToBase64(filePath : string) : string | null {
|
||
if (!isExists(filePath)) return null
|
||
const path = UTSHarmony.getResourcePath(filePath)
|
||
const file = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY);
|
||
// 获取文件状态
|
||
const stat = fileIo.statSync(path);
|
||
// 创建缓冲区
|
||
const buf = new ArrayBuffer(stat.size);
|
||
// 读取文件内容
|
||
// fileIo.read(fd, buf);
|
||
fileIo.readSync(file.fd, buf);
|
||
fileIo.closeSync(file);
|
||
// 转换为Base64
|
||
let base64Helper = new util.Base64Helper();
|
||
let array = new Uint8Array(buf);
|
||
let result = base64Helper.encodeToStringSync(array, util.Type.MIME)
|
||
return result
|
||
|
||
}
|
||
|
||
export function fileToDataURL(filePath : string) : string | null {
|
||
try {
|
||
const base64 = fileToBase64(filePath)
|
||
if (!base64) return null
|
||
const extension = getFileExtension(filePath);
|
||
const mimeType = getMimeType(extension);
|
||
return `data:${mimeType};base64,${base64}`;
|
||
} catch (err) {
|
||
return null
|
||
}
|
||
}
|
||
|
||
export function dataURLToFile(dataURL : string, filename : NullableString = null) : string | null {
|
||
// 格式校验正则表达式
|
||
const dataURLRegex = /^data:([a-zA-Z]+\/[a-zA-Z0-9-+.]+(;[a-zA-Z0-9-]+=[a-zA-Z0-9-]+)*)?(;base64)?,(.*)$/;
|
||
const match = dataURL.match(dataURLRegex);
|
||
|
||
const commaIndex = dataURL.indexOf(",");
|
||
const mimeType = dataURL.substring(0, commaIndex).replace("data:", "").replace(";base64", "");
|
||
const mimeTypeParts = mimeType.split("/");
|
||
|
||
if (!match) return null
|
||
|
||
const mediaType = match[1] || 'text/plain';
|
||
const extension = Object.entries(mimeTypeMap).find(it => it[1] == mediaType)?.[0] ?? mimeTypeParts[1]
|
||
if(!extension) return null
|
||
const base64 = dataURL.substring(commaIndex + 1);
|
||
const tempFileName = filename ?? `${Date.now()}.${extension}`
|
||
|
||
const tempDirPath = `${getEnv().TEMP_PATH}/file`
|
||
const tempFilePath : string = `${tempDirPath}/${tempFileName}`
|
||
if (!fileIo.accessSync(tempDirPath)) {
|
||
fileIo.mkdirSync(tempDirPath, true)
|
||
}
|
||
try {
|
||
const uint8Array = buffer.from(base64, 'base64').buffer
|
||
const file = fileIo.openSync(tempFilePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE);
|
||
fileIo.writeSync(file.fd, uint8Array);
|
||
|
||
return tempFilePath
|
||
|
||
} catch(err) {
|
||
return null
|
||
}
|
||
}
|
||
|
||
|
||
export function processFile(options : ProcessFileOptions) {
|
||
if (options.type == 'toBase64') {
|
||
const res = fileToBase64(options.path)
|
||
const err = 'fileToBase64: 解析失败'
|
||
if (res) {
|
||
options.success?.(res)
|
||
options.complete?.(res)
|
||
} else {
|
||
options.complete?.(err)
|
||
options.fail?.(err)
|
||
}
|
||
} else if (options.type == 'toDataURL') {
|
||
const res = fileToDataURL(options.path)
|
||
const err = 'fileToDataURL: 解析失败'
|
||
if (res) {
|
||
options.success?.(res)
|
||
options.complete?.(res)
|
||
} else {
|
||
options.complete?.(err)
|
||
options.fail?.(err)
|
||
}
|
||
} else if (options.type == 'toFile') {
|
||
const res = dataURLToFile(options.path, options.filename)
|
||
const err = 'dataURLToFile: 解析失败'
|
||
if (res) {
|
||
options.success?.(res)
|
||
options.complete?.(res)
|
||
} else {
|
||
options.complete?.(err)
|
||
options.fail?.(err)
|
||
}
|
||
}
|
||
} |