遍历访问阿里云节点下的所有文件信息并写入excel文件

后台系统用的久了,由于图片替换和删除导致阿里云上存在大量系统不在使用的图片。阿里是按照所有图片和视频等文件总容量以及下载流量收费的。所以这些不用的图片和视频需要定期清理。

遍历访问阿里云节点下的所有文件信息,并写入excel文件(阿里云文件数据表)。从阿里云中查到的图片文件地址都是http://开头的,要替换成https://开头的.

导入头文件和静态变量

复制代码
const FspConstant = require('@app/tools/fsp_constant.js');
const Tool = require('@app/tools/common_tool.js');
const msgCode = require('@app/config/error_config.js');
const Excel = require('exceljs');
const fs = require('fs');
const path = require('path');
const https = require('https');
const OSS = require('ali-oss');
const ossHZ = new OSS({
    region: 'oss-cn-hangzhou',
    accessKeyId: FspConstant.ACCESS_KEY_ID,
    accessKeySecret: FspConstant.ACCESS_KEY_SECRET,
    bucket: '具体的bucket名称',
});

实现代码:

复制代码
//获取阿里云节点下除了wx-test目录及子目录文件的所有文件
DeleteRepeatImageVideoTool.getAllFileUrlsWithPagination = async function(prefix = '') {
    const allFiles = [];
    let marker = null;
    // 定义要忽略的文件夹列表
    const ignoreFolders = [ 'wx-test'];

    try {
        do {
            const result = await ossHZ.list({
                prefix: prefix,
                delimiter: '/',
                'max-keys': 1000,
                marker: marker
            }, {});

            // 处理文件 - 过滤掉目录
            if (result.objects) {
                for (const object of result.objects) {
                    // 只处理真正的文件,不处理目录
                    if (!object.name.endsWith('/') && object.size > 0) {
                        let url = ossHZ.generateObjectUrl(object.name);
                        url = url.replace('http://fangsuanpan.oss-cn-hangzhou.aliyuncs.com/', 'https://fangsuanpan.oss-cn-hangzhou.aliyuncs.com/');
                        // 提取根目录
                        let rootDir = '';
                        const firstSlashIndex = object.name.indexOf('/');
                        if (firstSlashIndex !== -1) {
                            rootDir = object.name.substring(0, firstSlashIndex);
                        } else {
                            // 如果没有斜杠,说明文件在根目录下
                            rootDir = 'root';
                        }
                        allFiles.push({
                            name: object.name,
                            url: url,
                            size: object.size,
                            lastModified: object.lastModified,
                            type: object.type,
                            dir: rootDir
                        });
                    }
                }
            }

            // 递归处理子目录
            if (result.prefixes) {
                for (const subPrefix of result.prefixes) {
                    // 检查是否在忽略列表中
                    const shouldIgnore = ignoreFolders.some(folder => 
                        subPrefix.startsWith(folder + '/') || subPrefix === folder
                    );
                    
                    if (shouldIgnore) {
                        console.log(`忽略文件夹: ${subPrefix}`);
                        continue; // 跳过这个文件夹
                    }
                    
                    console.log(`遍历子目录: ${subPrefix}`);
                    const subFiles = await this.getAllFileUrlsWithPagination(subPrefix);
                    // 确保subFiles是数组
                    if (Array.isArray(subFiles)) {
                        allFiles.push(...subFiles);
                    } else if (subFiles && Array.isArray(subFiles.allFiles)) {
                        allFiles.push(...subFiles.allFiles);
                    }
                    // console.log(`遍历子目录: ${subPrefix}`);
                    // const subFiles = await this.getAllFileUrlsWithPagination(subPrefix);
                    // // 确保subFiles是数组
                    // if (Array.isArray(subFiles)) {
                    //     allFiles.push(...subFiles);
                    // } else if (subFiles && Array.isArray(subFiles.allFiles)) {
                    //     allFiles.push(...subFiles.allFiles);
                    // }
                }
            }

            marker = result.nextMarker;
            console.log(`已找到 ${allFiles.length} 个文件,继续标记: ${marker}`);
            // break;    
        } while (marker);

        // 如果是顶层调用,生成Excel;否则返回文件数组
        if (prefix === '') {
            if(Tool.checkNotEmptArray(allFiles)){
                let excel = Tool.makeExcel(allFiles, ['name', 'url', 'size','lastModified', 'type', 'dir'], {
                    name: '文件路径',
                    url: '文件地址',
                    size: '文件大小',
                    lastModified: '最后修改时间',
                    type: '类型',
                    dir: '根目录' 
                });
                return {excel, fileCount: allFiles.length};
            }else{
                return {fileCount: 0};
            }
        } else {
            // 递归调用返回文件数组
            return allFiles;
        }
    } catch (error) {
        console.error('分页遍历失败:', error);
        throw msgCode[39522]('获取图片列表');
    }
};

若遍历并写入所有文件信息到excel这部分代码修改为这样:

复制代码
                    const shouldIgnore = false;
                    // ignoreFolders.some(folder => 
                    //     subPrefix.startsWith(folder + '/') || subPrefix === folder
                    // );
相关推荐
倔强的石头_7 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤2 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区3 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
AI全栈实验室4 天前
MongoDB迁移金仓踩了5个坑,最后一个差点回滚
mongodb
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
加号34 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏4 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐4 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再4 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip