目录结构:

    1. ├── a.txt
    2. ├── b.txt
    3. ├── c.txt
    4. ├── files
    5. └── index.js

    index.js 文件:

    1. const fs = require('fs').promises;
    2. const path = require('path');
    3. /**
    4. * Move files by directory
    5. * @param {String} directory
    6. */
    7. async function moveFilesByDirectory(directory, inputExtname) {
    8. const dirEntries = await fs.readdir(directory, { withFileTypes: true });
    9. for (const dirEntry of dirEntries) {
    10. if (dirEntry.isFile()) {
    11. const { name: filename, ext } = path.parse(dirEntry.name);
    12. const extname = ext.split('.').pop().toLocaleLowerCase();
    13. if (extname === inputExtname) {
    14. const dir = path.join(directory, filename)
    15. await mkdir(dir);
    16. const sourcePath = path.join(directory, dirEntry.name);
    17. const destPath = path.join(dir, dirEntry.name);
    18. console.log(sourcePath, destPath);
    19. await mv(sourcePath, destPath);
    20. }
    21. }
    22. }
    23. }
    24. moveFilesByDirectory('./files', 'txt');
    25. /**
    26. * Create a directory
    27. * @param {String} dir
    28. * @returns
    29. */
    30. async function mkdir(dir) {
    31. if (!(await exists(dir))) {
    32. await fs.mkdir(dir);
    33. }
    34. return dir;
    35. }
    36. /**
    37. * Check if the file exists
    38. * @param {String} file
    39. * @returns
    40. */
    41. async function exists(file) {
    42. try {
    43. await fs.access(file);
    44. return true;
    45. } catch (err) {
    46. return false;
    47. }
    48. }
    49. /**
    50. * Move
    51. * @param {String} sourcePath
    52. * @param {String} destPath
    53. * @returns
    54. */
    55. async function mv(sourcePath, destPath) {
    56. try {
    57. await fs.rename(sourcePath, destPath);
    58. } catch (error) {
    59. if (error.code === 'EXDEV') {
    60. const readStream = fs.createReadStream(sourcePath);
    61. const writeStream = fs.createWriteStream(destPath);
    62. return new Promise((resolve, reject) => {
    63. readStream.pipe(writeStream);
    64. readStream.on('end', onClose);
    65. readStream.on('error', onError);
    66. async function onClose() {
    67. await fsPromises.unlink(sourcePath);
    68. resolve();
    69. }
    70. function onError(err) {
    71. console.error(`File write failed with message: ${err.message}`);
    72. writeStream.close();
    73. reject(err)
    74. }
    75. })
    76. }
    77. throw error;
    78. }
    79. }