FileHelper.ets 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. import fileUri from '@ohos.file.fileuri';
  2. import fs, { ListFileOptions, ReadOptions, ReadTextOptions, WriteOptions } from '@ohos.file.fs';
  3. import { BusinessError } from '@kit.BasicServicesKit';
  4. import { StrHelper } from './StrHelper';
  5. import { hilog } from '@kit.PerformanceAnalysisKit';
  6. import { image } from '@kit.ImageKit';
  7. import { buffer } from '@kit.ArkTS';
  8. import { LogHelper } from './LogHelper';
  9. import { ToolsHelper } from './ToolsHelper';
  10. import { photoAccessHelper } from '@kit.MediaLibraryKit';
  11. import { GlobalContext } from '../ContextConfig';
  12. export class FileHelper {
  13. private constructor() {
  14. }
  15. static readonly separator: string = '/';
  16. /**
  17. * 获取文件目录下的文件夹路径或文件路径。
  18. * @param dirPath 文件路径;支持完整路径和相对路径(download/wps/doc);dirPath传空字符串表示根目录
  19. * @param fileName 文件名(test.text);fileName传空字符串表示文件夹路径
  20. * @param blHap true:HAP级别文件路径、 false:App级别文件路径
  21. * @returns
  22. */
  23. static getFilesDirPath(dirPath: string = "", fileName: string = "", blHap: boolean = true): string {
  24. let filePath = blHap ? getContext().filesDir : getContext().getApplicationContext().filesDir; //根目录
  25. if (StrHelper.isNotEmpty(dirPath)) {
  26. if (StrHelper.startsWith(dirPath, filePath)) { //路径中包含根目录,是完整路径。
  27. filePath = dirPath;
  28. } else { //路径中不包含根目录,拼接成完整路径。
  29. filePath = filePath + FileHelper.separator + dirPath;
  30. }
  31. if (!FileHelper.accessSync(filePath)) {
  32. FileHelper.mkdirSync(filePath) //如果文件夹不存在就创建
  33. }
  34. }
  35. if (StrHelper.isNotEmpty(fileName)) {
  36. filePath = filePath + FileHelper.separator + fileName;
  37. }
  38. return filePath;
  39. }
  40. /**
  41. * 获取缓存目录下的文件夹路径或文件路径。
  42. * @param dirPath 文件路径;支持完整路径和相对路径(download/wps/doc);dirPath传空字符串表示根目录
  43. * @param fileName 文件名(test.text);fileName传空字符串表示文件夹路径
  44. * @param blHap true:HAP级别文件路径、 false:App级别文件路径
  45. * @returns
  46. */
  47. static getCacheDirPath(dirPath: string = "", fileName: string = "", blHap: boolean = true): string {
  48. let filePath = blHap ? getContext().cacheDir : getContext().getApplicationContext().cacheDir; //根目录
  49. if (StrHelper.isNotEmpty(dirPath)) {
  50. if (FileHelper.hasDirPath(dirPath)) { //路径中包含根目录,是完整路径。
  51. filePath = dirPath;
  52. } else { //路径中不包含根目录,拼接成完整路径。
  53. filePath = filePath + FileHelper.separator + dirPath;
  54. }
  55. if (!FileHelper.accessSync(filePath)) {
  56. FileHelper.mkdirSync(filePath) //如果文件夹不存在就创建
  57. }
  58. }
  59. if (StrHelper.isNotEmpty(fileName)) {
  60. filePath = filePath + FileHelper.separator + fileName;
  61. }
  62. return filePath;
  63. }
  64. /**
  65. * 获取临时目录下的文件夹路径或文件路径。
  66. * @param dirPath 文件路径;支持完整路径和相对路径(download/wps/doc);dirPath传空字符串表示根目录
  67. * @param fileName 文件名(test.text);fileName传空字符串表示文件夹路径
  68. * @param blHap true:HAP级别文件路径、 false:App级别文件路径
  69. * @returns
  70. */
  71. static getTempDirPath(dirPath: string = "", fileName: string = "", blHap: boolean = true): string {
  72. let filePath = blHap ? getContext().tempDir : getContext().getApplicationContext().tempDir; //根目录
  73. if (StrHelper.isNotEmpty(dirPath)) {
  74. if (FileHelper.hasDirPath(dirPath)) { //路径中包含根目录,是完整路径。
  75. filePath = dirPath;
  76. } else { //路径中不包含根目录,拼接成完整路径。
  77. filePath = filePath + FileHelper.separator + dirPath;
  78. }
  79. if (!FileHelper.accessSync(filePath)) {
  80. FileHelper.mkdirSync(filePath) //如果文件夹不存在就创建
  81. }
  82. }
  83. if (StrHelper.isNotEmpty(fileName)) {
  84. filePath = filePath + FileHelper.separator + fileName;
  85. }
  86. return filePath;
  87. }
  88. /**
  89. * 判断是否是完整路径
  90. * @param path 文件路径
  91. */
  92. static hasDirPath(path: string): boolean {
  93. return StrHelper.startsWith(path, "/data/storage/el1/") || StrHelper.startsWith(path, "/data/storage/el2/");
  94. }
  95. /**
  96. * 通过URI或路径,获取FileUri
  97. * @param uriOrPath URI或路径
  98. * @returns
  99. */
  100. static getFileUri(uriOrPath: string): fileUri.FileUri {
  101. return new fileUri.FileUri(uriOrPath);
  102. }
  103. /**
  104. * 通过URI或路径,获取文件名。
  105. * @param uriOrPath URI或路径
  106. * @returns
  107. */
  108. static getFileName(uriOrPath: string): string {
  109. return FileHelper.getFileUri(uriOrPath).name;
  110. }
  111. /**
  112. * 通过URI或路径,获取文件路径
  113. * @param uriOrPath URI或路径
  114. * @returns
  115. */
  116. static getFilePath(uriOrPath: string): string {
  117. return FileHelper.getFileUri(uriOrPath).path;
  118. }
  119. /**
  120. * 通过URI或路径,获取对应文件父目录的URI。
  121. * @param uriOrPath URI或路径
  122. */
  123. static getParentUri(uriOrPath: string): string {
  124. return FileHelper.getFileUri(uriOrPath).getFullDirectoryUri();
  125. }
  126. /**
  127. * 通过URI或路径,获取对应文件父目录的路径名。
  128. * @param uriOrPath URI或路径
  129. */
  130. static getParentPath(uriOrPath: string): string {
  131. let parentUri = FileHelper.getParentUri(uriOrPath);
  132. return FileHelper.getFilePath(parentUri)
  133. }
  134. /**
  135. * 以同步方法获取文件URI。
  136. * @param path 应用沙箱路径
  137. * @returns
  138. */
  139. static getUriFromPath(path: string): string {
  140. return fileUri.getUriFromPath(path);
  141. }
  142. /**
  143. * 根据文件名获取文件后缀
  144. * @param fileName 例如: test.txt test.doc
  145. * @returns
  146. */
  147. static getFileExtention(fileName: string) {
  148. if (StrHelper.isNotEmpty(fileName) && fileName.includes(".")) {
  149. return fileName.substring(fileName.lastIndexOf(".") + 1);
  150. }
  151. return '';
  152. }
  153. /**
  154. * 获取指定文件夹下所有文件的大小或指定文件大小。
  155. * @param path 文件夹路径 或 文件路径
  156. */
  157. static getFileDirSize(path: string): number {
  158. if (FileHelper.accessSync(path)) { //path存在
  159. if (FileHelper.isDirectory(path)) { //文件夹
  160. let count: number = 0;
  161. FileHelper.listFileSync(path, { recursion: true }).forEach((filePath) => {
  162. count = count + FileHelper.lstatSync(path + filePath).size
  163. })
  164. return count;
  165. } else { //文件
  166. return FileHelper.lstatSync(path).size
  167. }
  168. }
  169. return 0;
  170. }
  171. /**
  172. * 判断文件是否是普通文件。
  173. * @param file string|number 文件应用沙箱路径path或已打开的文件描述符fd。
  174. * @returns
  175. */
  176. static isFile(file: string | number): boolean {
  177. return fs.statSync(file).isFile();
  178. }
  179. /**
  180. * 判断文件是否是目录。
  181. * @param file string|number 文件应用沙箱路径path或已打开的文件描述符fd。
  182. * @returns
  183. */
  184. static isDirectory(file: string | number): boolean {
  185. return fs.statSync(file).isDirectory();
  186. }
  187. /**
  188. * 重命名文件或文件夹,使用Promise异步回调。
  189. * @param oldPath string 文件的应用沙箱原路径。
  190. * @param newPath string 文件的应用沙箱新路径。
  191. * @returns
  192. */
  193. static rename(oldPath: string, newPath: string): Promise<void> {
  194. return fs.rename(oldPath, newPath);
  195. }
  196. /**
  197. * 重命名文件或文件夹,以同步方法。
  198. * @param oldPath string 文件的应用沙箱原路径。
  199. * @param newPath string 文件的应用沙箱新路径。
  200. * @returns
  201. */
  202. static renameSync(oldPath: string, newPath: string) {
  203. fs.renameSync(oldPath, newPath);
  204. }
  205. /**
  206. * 创建目录,当recursion指定为true,可多层级创建目录,使用Promise异步回调。
  207. * @param path 目录的应用沙箱路径。
  208. * @param recursion 是否多层级创建目录。recursion指定为true时,可多层级创建目录。recursion指定为false时,仅可创建单层目录。
  209. * @returns
  210. */
  211. static mkdir(path: string, recursion: boolean = true): Promise<void> {
  212. if (recursion) {
  213. return fs.mkdir(path, recursion);
  214. } else {
  215. return fs.mkdir(path);
  216. }
  217. }
  218. /**
  219. * 创建目录以同步方法,当recursion指定为true,可多层级创建目录。
  220. * @param path 目录的应用沙箱路径。
  221. * @param recursion 是否多层级创建目录。recursion指定为true时,可多层级创建目录。recursion指定为false时,仅可创建单层目录。
  222. */
  223. static mkdirSync(path: string, recursion: boolean = true) {
  224. if (recursion) {
  225. fs.mkdirSync(path, recursion);
  226. } else {
  227. fs.mkdirSync(path);
  228. }
  229. }
  230. /**
  231. * 删除整个目录,使用Promise异步回调。
  232. * @param path 目录的应用沙箱路径。
  233. * @returns
  234. */
  235. static rmdir(path: string): Promise<void> {
  236. return fs.rmdir(path);
  237. }
  238. /**
  239. * 删除整个目录,以同步方法。
  240. * @param path 目录的应用沙箱路径。
  241. */
  242. static rmdirSync(path: string) {
  243. return fs.rmdirSync(path);
  244. }
  245. /**
  246. * 删除单个文件,使用Promise异步回调。
  247. * @param path 文件的应用沙箱路径。
  248. * @returns
  249. */
  250. static unlink(path: string): Promise<void> {
  251. return fs.unlink(path);
  252. }
  253. /**
  254. * 删除单个文件,以同步方法。
  255. * @param path 文件的应用沙箱路径。
  256. * @returns
  257. */
  258. static unlinkSync(path: string) {
  259. fs.unlinkSync(path);
  260. }
  261. /**
  262. * 检查文件是否存在,使用Promise异步回调。
  263. * @param path 文件应用沙箱路径。
  264. * @returns
  265. */
  266. static access(path: string): Promise<boolean> {
  267. return fs.access(path);
  268. }
  269. /**
  270. * 检查文件是否存在,以同步方法。
  271. * @param path 文件应用沙箱路径。
  272. * @returns
  273. */
  274. static accessSync(path: string): boolean {
  275. return fs.accessSync(path);
  276. }
  277. static getFileFd(uri: string) {
  278. let file = FileHelper.openSync(uri, fs.OpenMode.READ_ONLY)
  279. return file.fd
  280. }
  281. /**
  282. * 图片转base64
  283. * @param photoUri
  284. * @returns
  285. */
  286. static BmpToBase64(photoUri: string): Promise<string> {
  287. const imagePackerApi: image.ImagePacker = image.createImagePacker();
  288. const packOpts: image.PackingOption = { format: 'image/jpeg', quality: 100 };
  289. return new Promise<string>((resolve, reject) => {
  290. let file = FileHelper.openSync(photoUri, fs.OpenMode.READ_ONLY)
  291. const imageSource = image.createImageSource(file.fd);
  292. LogHelper.error('file.fd:' + file.fd)
  293. imageSource.createPixelMap().then((pixelMap) => {
  294. imagePackerApi.packing(pixelMap, packOpts).then((data: ArrayBuffer) => {
  295. let buf: buffer.Buffer = buffer.from(data);
  296. LogHelper.error('data:' + data)
  297. resolve(buf.toString('base64'))
  298. }).catch((err: BusinessError) => {
  299. LogHelper.error('packing failed with err: ' + JSON.stringify(err));
  300. reject(err)
  301. })
  302. }).catch((err: BusinessError) => {
  303. LogHelper.error('createPixelMap failed with err: ' + JSON.stringify(err));
  304. reject(err)
  305. });
  306. })
  307. }
  308. /**
  309. * 保存图片到相册,需要注意权限
  310. * @param pixmap
  311. */
  312. static saveImage(pixmap: image.PixelMap): Promise<string> {
  313. return new Promise<string>(async (resolve, reject) => {
  314. let imageBuffer: ArrayBuffer = new ArrayBuffer(1);
  315. try {
  316. imageBuffer = await image.createImagePacker().packing(pixmap, { format: "image/png", quality: 100 });
  317. } catch (err) {
  318. ToolsHelper.showMessage('保存失败');
  319. console.error(`Invoke packingPixelMap2Jpg failed, err: ${JSON.stringify(err)}`);
  320. reject()
  321. return;
  322. }
  323. const uri = await photoAccessHelper.getPhotoAccessHelper(GlobalContext.getContext())
  324. .createAsset(photoAccessHelper.PhotoType.IMAGE, 'png');
  325. fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
  326. .then(async (file) => {
  327. try {
  328. await fs.write(file.fd, imageBuffer);
  329. ToolsHelper.showMessage('保存成功');
  330. } finally {
  331. await fs.close(file.fd); // 确保文件关闭
  332. }
  333. resolve(uri);
  334. }).catch(() => {
  335. ToolsHelper.showMessage('保存失败');
  336. reject()
  337. return;
  338. });
  339. });
  340. }
  341. /**
  342. * 打开文件,支持使用URI打开文件。使用Promise异步回调。
  343. * @param path string 文件的应用沙箱路径或URI。
  344. * @param mode number 打开文件的选项,必须指定如下选项中的一个,默认以只读方式打开。
  345. * @returns
  346. */
  347. static open(path: string, mode: number = fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE): Promise<fs.File> {
  348. return fs.open(path, mode);
  349. }
  350. /**
  351. * 打开文件,支持使用URI打开文件。以同步方法。
  352. * @param path string 文件的应用沙箱路径或URI。
  353. * @param mode number 打开文件的选项,必须指定如下选项中的一个,默认以只读方式打开。
  354. * @returns
  355. */
  356. static openSync(path: string, mode: number = fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE): fs.File {
  357. return fs.openSync(path, mode);
  358. }
  359. /**
  360. * 从文件读取数据,使用Promise异步回调。
  361. * @param fd number 已打开的文件描述符。
  362. * @param buffer ArrayBuffer 用于保存读取到的文件数据的缓冲区。
  363. * @param options 支持如下选项:
  364. * offset,number类型,表示期望读取文件的位置。可选,默认从当前位置开始读。
  365. * length,number类型,表示期望读取数据的长度。可选,默认缓冲区长度。
  366. * @returns
  367. */
  368. static read(fd: number, buffer: ArrayBuffer, options?: ReadOptions): Promise<number> {
  369. return fs.read(fd, buffer, options)
  370. }
  371. /**
  372. * 从文件读取数据,以同步方法。
  373. * @param fd number 已打开的文件描述符。
  374. * @param buffer ArrayBuffer 用于保存读取到的文件数据的缓冲区。
  375. * @param options 支持如下选项:
  376. * offset,number类型,表示期望读取文件的位置。可选,默认从当前位置开始读。
  377. * length,number类型,表示期望读取数据的长度。可选,默认缓冲区长度。
  378. * @returns
  379. */
  380. static readSync(fd: number, buffer: ArrayBuffer, options?: ReadOptions): number {
  381. return fs.readSync(fd, buffer, options)
  382. }
  383. /**
  384. * 基于文本方式读取文件(即直接读取文件的文本内容),使用Promise异步回调。
  385. * @param filePath 文件的应用沙箱路径。
  386. * @param options 支持如下选项:
  387. * offset,number类型,表示期望读取文件的位置。可选,默认从当前位置开始读取。
  388. * length,number类型,表示期望读取数据的长度。可选,默认文件长度。
  389. * encoding,string类型,当数据是 string 类型时有效,表示数据的编码方式,默认 'utf-8',仅支持 'utf-8'。
  390. * @returns
  391. */
  392. static readText(filePath: string, options?: ReadTextOptions): Promise<string> {
  393. return fs.readText(filePath, options);
  394. }
  395. /**
  396. * 基于文本方式读取文件(即直接读取文件的文本内容),以同步方法。
  397. * @param filePath 文件的应用沙箱路径。
  398. * @param options 支持如下选项:
  399. * offset,number类型,表示期望读取文件的位置。可选,默认从当前位置开始读取。
  400. * length,number类型,表示期望读取数据的长度。可选,默认文件长度。
  401. * encoding,string类型,当数据是 string 类型时有效,表示数据的编码方式,默认 'utf-8',仅支持 'utf-8'。
  402. * @returns
  403. */
  404. static readTextSync(filePath: string, options?: ReadTextOptions): string {
  405. return fs.readTextSync(filePath, options);
  406. }
  407. /**
  408. * 将数据写入文件,使用Promise异步回调。
  409. * @param fd number 已打开的文件描述符。
  410. * @param buffer ArrayBuffer|string 待写入文件的数据,可来自缓冲区或字符串。
  411. * @param options 支持如下选项:
  412. * offset,number类型,表示期望写入文件的位置。可选,默认从当前位置开始写。
  413. * length,number类型,表示期望写入数据的长度。可选,默认缓冲区长度。
  414. * encoding,string类型,当数据是string类型时有效,表示数据的编码方式,默认 'utf-8'。当前仅支持 'utf-8'。
  415. * @returns
  416. */
  417. static write(fd: number, buffer: ArrayBuffer | string, options?: WriteOptions): Promise<number> {
  418. return fs.write(fd, buffer, options)
  419. }
  420. /**
  421. * 将数据写入文件,以同步方法。
  422. * @param fd number 已打开的文件描述符。
  423. * @param buffer ArrayBuffer|string 待写入文件的数据,可来自缓冲区或字符串。
  424. * @param options 支持如下选项:
  425. * offset,number类型,表示期望写入文件的位置。可选,默认从当前位置开始写。
  426. * length,number类型,表示期望写入数据的长度。可选,默认缓冲区长度。
  427. * encoding,string类型,当数据是string类型时有效,表示数据的编码方式,默认 'utf-8'。当前仅支持 'utf-8'。
  428. * @returns
  429. */
  430. static writeSync(fd: number, buffer: ArrayBuffer | string, options?: WriteOptions): number {
  431. return fs.writeSync(fd, buffer, options)
  432. }
  433. /**
  434. * 将数据写入文件,并关闭文件。
  435. * @param path string 文件的应用沙箱路径或URI。
  436. * @param buffer ArrayBuffer|string 待写入文件的数据,可来自缓冲区或字符串。
  437. * @param append 是否追加,true-追加,false-不追加(直接覆盖)
  438. * @returns
  439. */
  440. static async writeEasy(path: string, buffer: ArrayBuffer | string, append: boolean = true): Promise<number> {
  441. try {
  442. let file = FileHelper.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  443. let offset = append ? FileHelper.statSync(file.fd).size : 0
  444. let options: WriteOptions = { offset: offset, encoding: 'utf-8' };
  445. return await FileHelper.write(file.fd, buffer, options).finally(() => {
  446. FileHelper.close(file.fd); //关闭文件
  447. });
  448. } catch (err) {
  449. let error = err as BusinessError;
  450. hilog.error(0x0000, '=====>', `FileHelper-writeEasy-异常 ~ code: ${error.code} -·- message: ${error.message}`)
  451. return -1;
  452. }
  453. }
  454. /**
  455. * 关闭文件,使用Promise异步回调。
  456. * @param file 已打开的File对象或已打开的文件描述符fd。
  457. * @returns
  458. */
  459. static close(file: fs.File | number): Promise<void> {
  460. return fs.close(file);
  461. }
  462. /**
  463. * 关闭文件,以同步方法。
  464. * @param file 已打开的File对象或已打开的文件描述符fd。
  465. */
  466. static closeSync(file: fs.File | number) {
  467. fs.closeSync(file);
  468. }
  469. /**
  470. * 列出文件夹下所有文件名,支持递归列出所有文件名(包含子目录下),支持文件过滤,使用Promise异步回调。
  471. * @param path string 文件夹的应用沙箱路径。
  472. * @param options 文件过滤选项。默认不进行过滤。
  473. * recursion boolean 是否递归子目录下文件名,默认为false。
  474. * listNum number 列出文件名数量。当设置0时,列出所有文件,默认为0。
  475. * filter Filter 文件过滤选项。当前仅支持后缀名匹配、文件名模糊查询、文件大小过滤、最近修改时间过滤。
  476. * @returns
  477. */
  478. static listFile(path: string, options?: ListFileOptions): Promise<string[]> {
  479. return fs.listFile(path, options);
  480. }
  481. /**
  482. * 列出文件夹下所有文件名,支持递归列出所有文件名(包含子目录下),支持文件过滤,以同步方法。
  483. * @param path string 文件夹的应用沙箱路径。
  484. * @param options 文件过滤选项。默认不进行过滤。
  485. * recursion boolean 是否递归子目录下文件名,默认为false。
  486. * listNum number 列出文件名数量。当设置0时,列出所有文件,默认为0。
  487. * filter Filter 文件过滤选项。当前仅支持后缀名匹配、文件名模糊查询、文件大小过滤、最近修改时间过滤。
  488. * @returns
  489. */
  490. static listFileSync(path: string, options?: ListFileOptions): string[] {
  491. return fs.listFileSync(path, options);
  492. }
  493. /**
  494. * 获取文件详细属性信息,使用Promise异步回调。
  495. * @param file string|number 文件应用沙箱路径path或已打开的文件描述符fd。
  496. */
  497. static stat(file: string | number): Promise<fs.Stat> {
  498. return fs.stat(file);
  499. }
  500. /**
  501. * 获取文件详细属性信息,以同步方法。
  502. * @param file string|number 文件应用沙箱路径path或已打开的文件描述符fd。
  503. * @returns
  504. */
  505. static statSync(file: string | number): fs.Stat {
  506. return fs.statSync(file);
  507. }
  508. /**
  509. * 拷贝文件或者目录,支持拷贝进度监听,使用Promise异步返回。
  510. * @param srcUri 待复制文件或目录的uri。
  511. * @param destUri 目标文件或目录的uri。
  512. * @param options options中提供拷贝进度回调:
  513. * ProgressListener 拷贝进度监听。
  514. * @returns
  515. */
  516. static copy(srcUri: string, destUri: string, options?: fs.CopyOptions): Promise<void> {
  517. return fs.copy(srcUri, destUri, options);
  518. }
  519. /**
  520. * 复制文件,使用Promise异步回调。
  521. * @param src string|number 待复制文件的路径或待复制文件的文件描述符。
  522. * @param dest string|number 目标文件路径或目标文件的文件描述符。
  523. * @param mode number 提供覆盖文件的选项,当前仅支持0,且默认为0。0:完全覆盖目标文件。
  524. * @returns
  525. */
  526. static copyFile(src: string | number, dest: string | number, mode: number = 0): Promise<void> {
  527. return fs.copyFile(src, dest, mode);
  528. }
  529. /**
  530. * 以同步方法复制文件。
  531. * @param src string|number 待复制文件的路径或待复制文件的文件描述符。
  532. * @param dest string|number 目标文件路径或目标文件的文件描述符。
  533. * @param mode number 提供覆盖文件的选项,当前仅支持0,且默认为0。0:完全覆盖目标文件。
  534. */
  535. static copyFileSync(src: string | number, dest: string | number, mode: number = 0) {
  536. fs.copyFileSync(src, dest, mode);
  537. }
  538. /**
  539. * 复制源文件夹至目标路径下,只能复制沙箱里的文件夹,使用Promise异步返回。
  540. * @param src 源文件夹的应用沙箱路径。
  541. * @param dest 目标文件夹的应用沙箱路径。
  542. * @param mode 复制模式:
  543. * mode为0,文件级别抛异常。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则抛出异常。源文件夹下未冲突的文件全部移动至目标文件夹下,目标文件夹下未冲突文件将继续保留,且冲突文件信息将在抛出异常的data属性中以Array<ConflictFiles>形式提供。
  544. * mode为1,文件级别强制覆盖。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则强制覆盖冲突文件夹下所有同名文件,未冲突文件将继续保留。
  545. * @returns
  546. */
  547. static copyDir(src: string, dest: string, mode: number = 1): Promise<void> {
  548. return fs.copyDir(src, dest, mode);
  549. }
  550. /**
  551. * 以同步方法复制源文件夹至目标路径下,只能复制沙箱里的文件夹。
  552. * @param src 源文件夹的应用沙箱路径。
  553. * @param dest 目标文件夹的应用沙箱路径。
  554. * @param mode 复制模式:
  555. * mode为0,文件级别抛异常。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则抛出异常。源文件夹下未冲突的文件全部移动至目标文件夹下,目标文件夹下未冲突文件将继续保留,且冲突文件信息将在抛出异常的data属性中以Array<ConflictFiles>形式提供。
  556. * mode为1,文件级别强制覆盖。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则强制覆盖冲突文件夹下所有同名文件,未冲突文件将继续保留。
  557. * @returns
  558. */
  559. static copyDirSync(src: string, dest: string, mode: number = 1) {
  560. fs.copyDirSync(src, dest, mode);
  561. }
  562. /**
  563. * 移动文件,使用Promise异步回调。
  564. * @param src string 源文件的应用沙箱路径。
  565. * @param dest string 目的文件的应用沙箱路径。
  566. * @param mode number 移动模式。若mode为0,移动位置存在同名文件时,强制移动覆盖。若mode为1,移动位置存在同名文件时,抛出异常。默认为0。
  567. * @returns
  568. */
  569. static moveFile(src: string, dest: string, mode: number = 0): Promise<void> {
  570. return fs.moveFile(src, dest, mode)
  571. }
  572. /**
  573. * 移动文件,以同步方法。
  574. * @param src string 源文件的应用沙箱路径。
  575. * @param dest string 目的文件的应用沙箱路径。
  576. * @param mode number 移动模式。若mode为0,移动位置存在同名文件时,强制移动覆盖。若mode为1,移动位置存在同名文件时,抛出异常。默认为0。
  577. * @returns
  578. */
  579. static moveFileSync(src: string, dest: string, mode: number = 0) {
  580. fs.moveFileSync(src, dest, mode)
  581. }
  582. /**
  583. * 移动源文件夹至目标路径下,使用Promise异步返回。
  584. * @param src 源文件夹的应用沙箱路径
  585. * @param dest 目标文件夹的应用沙箱路径
  586. * @param mode 移动模式:
  587. * mode为0,文件夹级别抛异常。若目标文件夹下存在与源文件夹名冲突的非空文件夹,则抛出异常。
  588. * mode为1,文件级别抛异常。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则抛出异常。源文件夹下未冲突的文件全部移动至目标文件夹下,目标文件夹下未冲突文件将继续保留,且冲突文件信息将在抛出异常的data属性中以Array<ConflictFiles>形式提供。
  589. * mode为2,文件级别强制覆盖。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则强制覆盖冲突文件夹下所有同名文件,未冲突文件将继续保留。
  590. * mode为3,文件夹级别强制覆盖。移动源文件夹至目标文件夹下,目标文件夹下移动的文件夹内容与源文件夹完全一致。若目标文件夹下存在与源文件夹名冲突的文件夹,该文件夹下所有原始文件将不会保留。
  591. * @returns
  592. */
  593. static moveDir(src: string, dest: string, mode: number = 3): Promise<void> {
  594. return fs.moveDir(src, dest, mode);
  595. }
  596. /**
  597. * 以同步方法移动源文件夹至目标路径下。
  598. * @param src 源文件夹的应用沙箱路径
  599. * @param dest 目标文件夹的应用沙箱路径
  600. * @param mode 移动模式:
  601. * mode为0,文件夹级别抛异常。若目标文件夹下存在与源文件夹名冲突的非空文件夹,则抛出异常。
  602. * mode为1,文件级别抛异常。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则抛出异常。源文件夹下未冲突的文件全部移动至目标文件夹下,目标文件夹下未冲突文件将继续保留,且冲突文件信息将在抛出异常的data属性中以Array<ConflictFiles>形式提供。
  603. * mode为2,文件级别强制覆盖。目标文件夹下存在与源文件夹名冲突的文件夹,若冲突文件夹下存在同名文件,则强制覆盖冲突文件夹下所有同名文件,未冲突文件将继续保留。
  604. * mode为3,文件夹级别强制覆盖。移动源文件夹至目标文件夹下,目标文件夹下移动的文件夹内容与源文件夹完全一致。若目标文件夹下存在与源文件夹名冲突的文件夹,该文件夹下所有原始文件将不会保留。
  605. * @returns
  606. */
  607. static moveDirSync(src: string, dest: string, mode: number = 3) {
  608. return fs.moveDirSync(src, dest, mode);
  609. }
  610. /**
  611. * 截断文件,使用Promise异步回调。
  612. * @param file string|number 文件的应用沙箱路径或已打开的文件描述符fd。
  613. * @param len number 文件截断后的长度,以字节为单位。默认为0。
  614. * @returns
  615. */
  616. static truncate(file: string | number, len: number = 0): Promise<void> {
  617. return fs.truncate(file, len)
  618. }
  619. /**
  620. * 截断文件,以同步方法。
  621. * @param file string|number 文件的应用沙箱路径或已打开的文件描述符fd。
  622. * @param len number 文件截断后的长度,以字节为单位。默认为0。
  623. * @returns
  624. */
  625. static truncateSync(file: string | number, len: number = 0) {
  626. fs.truncateSync(file, len)
  627. }
  628. /**
  629. * 获取链接文件信息,使用Promise异步回调。
  630. * @param path string 文件的应用沙箱路径。
  631. * @returns
  632. */
  633. static lstat(path: string): Promise<fs.Stat> {
  634. return fs.lstat(path);
  635. }
  636. /**
  637. * 获取链接文件信息,以同步方法。
  638. * @param path string 文件的应用沙箱路径。
  639. * @returns
  640. */
  641. static lstatSync(path: string): fs.Stat {
  642. return fs.lstatSync(path);
  643. }
  644. /**
  645. * 同步文件数据,使用Promise异步回调。
  646. * @param fd number 已打开的文件描述符。
  647. * @returns
  648. */
  649. static fsync(fd: number): Promise<void> {
  650. return fs.fsync(fd);
  651. }
  652. /**
  653. * 同步文件数据,以同步方法。
  654. * @param fd number 已打开的文件描述符。
  655. */
  656. static fsyncSync(fd: number) {
  657. fs.fsyncSync(fd);
  658. }
  659. /**
  660. * 实现文件内容数据同步,使用Promise异步回调。
  661. * @param fd number 已打开的文件描述符。
  662. * @returns
  663. */
  664. static fdatasync(fd: number): Promise<void> {
  665. return fs.fdatasync(fd);
  666. }
  667. /**
  668. * 实现文件内容数据同步,以同步方法。
  669. * @param fd number 已打开的文件描述符。
  670. */
  671. static fdatasyncSync(fd: number) {
  672. fs.fdatasyncSync(fd);
  673. }
  674. /**
  675. * 基于文件路径打开文件流,使用Promise异步回调。
  676. * @param path string 文件的应用沙箱路径。
  677. * @param mode string 文件打开类型
  678. * r:打开只读文件,该文件必须存在。
  679. * r+:打开可读写的文件,该文件必须存在。
  680. * w:打开只写文件,若文件存在则文件长度清0,即该文件内容会消失。若文件不存在则建立该文件。
  681. * w+:打开可读写文件,若文件存在则文件长度清0,即该文件内容会消失。若文件不存在则建立该文件。
  682. * a:以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
  683. * a+:以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
  684. * @returns
  685. */
  686. static createStream(path: string, mode: string = 'r'): Promise<fs.Stream> {
  687. return fs.createStream(path, mode)
  688. }
  689. /**
  690. * 基于文件路径打开文件流,以同步方法。
  691. * @param path string 文件的应用沙箱路径。
  692. * @param mode string 文件打开类型
  693. * r:打开只读文件,该文件必须存在。
  694. * r+:打开可读写的文件,该文件必须存在。
  695. * w:打开只写文件,若文件存在则文件长度清0,即该文件内容会消失。若文件不存在则建立该文件。
  696. * w+:打开可读写文件,若文件存在则文件长度清0,即该文件内容会消失。若文件不存在则建立该文件。
  697. * a:以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
  698. * a+:以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
  699. * @returns
  700. */
  701. static createStreamSync(path: string, mode: string = 'r'): fs.Stream {
  702. return fs.createStreamSync(path, mode);
  703. }
  704. /**
  705. * 基于文件描述符打开文件流,使用Promise异步回调。
  706. * @param fd number 已打开的文件描述符。
  707. * @param mode string 文件打开类型
  708. * r:打开只读文件,该文件必须存在。
  709. * r+:打开可读写的文件,该文件必须存在。
  710. * w:打开只写文件,若文件存在则文件长度清0,即该文件内容会消失。若文件不存在则建立该文件。
  711. * w+:打开可读写文件,若文件存在则文件长度清0,即该文件内容会消失。若文件不存在则建立该文件。
  712. * a:以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
  713. * a+:以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
  714. * @returns
  715. */
  716. static fdopenStream(fd: number, mode: string = 'r'): Promise<fs.Stream> {
  717. return fs.fdopenStream(fd, mode)
  718. }
  719. /**
  720. * 基于文件描述符打开文件流,以同步方法。
  721. * @param fd number 已打开的文件描述符。
  722. * @param mode string 文件打开类型
  723. * r:打开只读文件,该文件必须存在。
  724. * r+:打开可读写的文件,该文件必须存在。
  725. * w:打开只写文件,若文件存在则文件长度清0,即该文件内容会消失。若文件不存在则建立该文件。
  726. * w+:打开可读写文件,若文件存在则文件长度清0,即该文件内容会消失。若文件不存在则建立该文件。
  727. * a:以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
  728. * a+:以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
  729. * @returns
  730. */
  731. static fdopenStreamSync(fd: number, mode: string = 'r'): fs.Stream {
  732. return fs.fdopenStreamSync(fd, mode)
  733. }
  734. /**
  735. * 创建临时目录,使用Promise异步回调。
  736. * @param prefix string 用随机产生的字符串替换以“XXXXXX”结尾目录路径。
  737. * @returns
  738. */
  739. static mkdtemp(prefix: string): Promise<string> {
  740. return fs.mkdtemp(prefix);
  741. }
  742. /**
  743. * 创建临时目录,以同步的方法。
  744. * @param prefix string 用随机产生的字符串替换以“XXXXXX”结尾目录路径。
  745. * @returns
  746. */
  747. static mkdtempSync(prefix: string): string {
  748. return fs.mkdtempSync(prefix);
  749. }
  750. /**
  751. * 将文件描述符转化为File。
  752. * @param fd 文件描述符。
  753. * @returns
  754. */
  755. static dup(fd: number): fs.File {
  756. return fs.dup(fd);
  757. }
  758. /**
  759. * 修改文件最近访问时间属性。
  760. * path 文件的应用沙箱路径。
  761. * mtime 待更新的时间戳。自1970年1月1日起至目标时间的毫秒数。仅支持修改文件最近访问时间属性。
  762. * @returns
  763. */
  764. static utimes(path: string, mtime: number): void {
  765. fs.utimes(path, mtime);
  766. }
  767. /**
  768. * 格式化文件大小
  769. * @param fileSize
  770. * @returns
  771. */
  772. static getFormatFileSize(fileSize: number): string {
  773. if (fileSize < 1024) {
  774. return fileSize + "B";
  775. } else if (fileSize < 1024 * 1024) {
  776. return (fileSize / 1024).toFixed(1) + "KB";
  777. } else if (fileSize < 1024 * 1024 * 1024) {
  778. return (fileSize / (1024 * 1024)).toFixed(1) + "MB";
  779. } else if (fileSize < 1024 * 1024 * 1024 * 1024) {
  780. return (fileSize / (1024 * 1024 * 1024)).toFixed(1) + "GB";
  781. } else {
  782. return (fileSize / (1024 * 1024 * 1024 * 1024)).toFixed(1) + "TB";
  783. }
  784. }
  785. }