在以下三种情况会执行文件清除策略,防止DropBox占用太多的空间:
- 设备低内存;
- setting配置发生变更;
- 添加文件 。
/** * Trims the files on disk to make sure they aren't using too much space. * @return the overall quota for storage (in bytes) */private synchronized long trimToFit() throws IOException {return mCachedQuotaBlocks * mBlockSize;}
2.3.2 文件删除及标记处理策略在上述策略不满足后,部分文件会被删除,删除后,会在DropBox添加一个.lost的空文件标记被删除的文件 。
2.3.3 文件类型管控
DropBoxMangerService对于可存储的文件类型也有控制,主要是对于TAG的控制 。
public boolean isTagEnabled(String tag) {}
2.3.4 权限管控【Android系统服务DropBoxManagerService详解与实践应用】使用DropBox需要READ_LOGS权限和PACKAGE_USAGE_STATS两个权限 。
2.4 读写策略这块涉及到DBMS几个关键方法和属性,主要涉及到初始化(init),添加文件(addEntry),获取文件(getNextEntry),文件类型(EntryFile) 。
DBMS作为系统服务会由SystemServer启动,添加文件(addEntry)和获取文件(getNextEntry)在调用时会先进行初始化(init) 。
其中每个文件都会转换成一个EntryFile类来管理,关系见下图:
文章插图
下面了解一下初始化,EntryFile,添加文件和获取文件的具体内容:
2.4.1 初始化
初始化会将DropBox文件列表缓存到内存中 。
/** If never run before, scans disk contents to build in-memory tracking data. */private synchronized void init() throws IOException {// 省略代码......File[] files = mDropBoxDir.listFiles(); // 列出所有文件for (File file : files) {EntryFile entry = new EntryFile(file, mBlockSize); // 一个日志文件对应一个EntryFile对象enrollEntry(entry); // 加入到mAllFiles}}
初始化的时机:- 设备存储容量低广播回调
- 设置配置项修改
- 添加日志文件
- 获取日志文件
- dump 命令行列出DropBox的一些内容
每个文件对应一个EntryFile,用block数来统计大小,DBMS涉及的读写都是根据磁盘的blockSize来进行,效率会更高 。
static final class EntryFile implements Comparable<EntryFile> {public final String tag; // 日志文件的tag,类型public final long timestampMillis; // 日志文件的时间戳public final int flags; // 日志文件的flag,标志TEXT,EMPTY,GZIPPEDpublic final int blocks; // 存放文件的块数}
2.4.3 添加文件添加一个日志文件,常见的在Ams中的addErrorToDropBox方法调用 。
添加文件管控策略
① .lost的文件格式不允许添加 。
// 如果添加.lost的文件,抛异常if ((flags & DropBoxManager.IS_EMPTY) != 0) throw new IllegalArgumentException();
② 配置不允许记录的TAG,不会被添加 。// 从设置里面读取这个tag是否被允许记录if (!isTagEnabled(tag)) return;
③ 根据系统设置的磁盘块大小进行写入,提高写入效率 。int bufferSize = mBlockSize;
④ 异常时间戳文件矫正:写入文件前会将超过当前时间10s的文件修改时间后重新命名并加入到缓存文件列表中 。// 找出当前时间10s之后的所有文件SortedSet<EntryFile> tail = mAllFiles.contents.tailSet(new EntryFile(t + 10000));EntryFile[] future = null;if (!tail.isEmpty()) {future = tail.toArray(new EntryFile[tail.size()]);tail.clear();// 从文件列表中mAllFiles清除掉超过当前时间的}// 省略代码......for (EntryFile late : future) {if ((late.flags & DropBoxManager.IS_EMPTY) == 0) { // 将这些超过当前时间的文件重命名,时间戳依次+1,并且重新加入到mAllFiles中enrollEntry(new EntryFile());}}
⑤ 添加文件的顺序,先创建临时文件,然后使用文件的rename方法,rename方法是原子操作,保证并发操作的安全 。
推荐阅读
- Go、Spring Boot、 Elixir 以及Helidon 微服务框架性能测试对比
- 招聘|学历成孔乙己的“长衫”?酒店到某211高校招服务员,破大防了
- 求职|湖北广播电视台后勤服务中心招聘7人
- 沈志莉|教育系统是清水衙门?这位落马女校长,一次美容就花69万
- 苏果供应商b2b服务系统_什么是B2B数字化供应链平台?
- 结构化布线网络系统及其基本组成部分
- 结构化布线系统的十大优势
- 永远不要在你的 Linux 系统上运行这些命令
- 人工智能热潮导致算力紧张,微软推新服务器租赁计划
- 选择美国服务器为什么推荐CN2线路?