记录《java网盘》中清理文件

本文探讨在云服务器上,如何有效回收未被用户关联的文件。通过对比单次查询所有和分批次查询加临时文件存储两种策略,解决大数据量下内存消耗过大的问题。

运行环境 CentOS7 1G内存 40G硬盘(某某云服务器,学生价9.5一个月)
数据表结构
在这里插入图片描述

硬盘中文件存放方式是:
以月为单位创建目录,同一个月的文件放在同一个目录中。
文件名格式为:时间戳+原始文件名
如:E:\development\upload\20196\1561637254739img.jpeg

数据库的file表存有文件的真实路径,user_file表则是用户表user与file表多对多的一个关联表,user_file表中的 link_id 字段是一个与 file 表关联的外键,当用户删除自己保存的文件时只是删除user_file表的记录,并不会直接删除file表中的记录,因为file可能还有其他用户关联。
当全部用户都没有关联该file记录时,该file记录就应该被删除,对应的文件也就应该被删除。

由于文件文件量比较大,数据库记录信息也比较多,所以需要在一个特定的时间去回收,使用spring的task组件,设置一个定时执行任务,设置在每天的凌晨3点进行文件回收

方式1,单次查询所有:

回收步骤:

  • 查询出全部user_filelink_id(封装成Long对象), 存放在一个List中, 命名为 linkIdList
  • 查询出全部 file 记录(每条记录封装成一个pojo的一个WPFile对象),也存放在一个List中, 命名为wpFileList
  • 比较两个List,取出wpFileListid 属性值不在linkIdList中的对象,将该对象的 filePath 属性存放在List中,命名为pathList,这个pathList中的路径则是没有用户关联的,路径对应的文件应该被删除。这些对象对应于file表中的记录也应该被删除。
    回收结束

这样子虽然能成功的回收文件,但是在小数据量时没有问题,在数据量大时就会出现内存消耗过大的问题。在一百万条数据时,wpFileList集合需要 163 m 内存, linkIdList需要 27m内存,当三百万条数据服务器就吃不消了,方法不可行。

方式2,分批次查询+临时文件存储:

既然一次过把所有文件都存入List中会造成内存消耗过大问题,那么能不能分批次进行查询,每一次只查询一部分(我暂时一次查100000条),这样wpFileList集合只需要 16 m左右的内存,linkIdList则只需要 2.7m左右内存,这样即使是数据库中有一千万或上亿条数据,也没关系,只要查询次数增加即可,不会出现瞬间内存爆炸的风险。
步骤:

  • 不断循环查询,每次查询十万条,直到数据查询完毕。每次查询的结果只取一部分有用的数据存入临时文件中。两个文件的查询方式类似。这样就得到了两个临时文件wpfile.txtuserfile.txtwpfile.txt 存放了file的id和文件路径,userfile.txt存放了link_id.
  • 比较wpfile.txt 的id 和userfile.txtlink_id , 如果在userfile.txt文件中没有wpfile.txtid对应值,表示wpfile.txt文件中的这一行数据应该被删除了(没有人关联他),记录在deletefile.txt临时文件中
  • 读取deletefile.txt每一行数据,一行(格式为:“id path”)中id 代表一条要数据库中file表中要删除的行,path代表硬盘中要删除文件的路径。删除即可

github地址为:https://github.com/liangjiegao/java-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值