前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >文件服务设计

文件服务设计

原创
作者头像
jerrypxiao
修改2019-07-02 10:31:43
2.4K0
修改2019-07-02 10:31:43
举报
文章被收录于专栏:音视频专栏音视频专栏

1. 概述

1.1 应用模块

作为项目的基础模块为各个项目提供统一的文件操作能力,文件服务提供给基础模块调用,基础模块再将其封装对外开放接口。

1.2 开发背景

新的App提供统一简明的接口,尽量覆盖更多的业务场景。提供基本的文件存储相关的接口。解决多人多团队开发的情况下,造成的文件存储的问题,如目录管理混乱,不同业务资源存储混乱,代码重复等。解决文件存储需要考虑的问题,如不同账户需要管理不同文件的问题,文件操作等级不同的问题等。

1.3 术语

腾讯云Cos系统

虚拟文件

2.调研分析

2.1 基本目标

这里的文件服务有几个层面的含义,分别是管理文件服务,操作文件服务。

管理文件服务

(1)划分文件存储的目录

(2)管理文件存储的位置

(3)定义目录的操作性,如是否可删除等

操作文件服务

(1)提供文件的读、写、新建、修改、删除、拷贝等操作;

(2)提供目录的新建、删除、移动、拷贝,遍历等操作;

2.2 业务相关性分析

这里我们头脑风暴一下,列举一下可能会用到文件服务或者跟文件操作比较多的模块。以此作为参考,一方面作为接口设计的参考,一方面来用来验证我们的文件服务是否适应多变的业务场景。

(1)图片、视频等,各种文件选择器

(2)配置文件的保存、匹配、完整性检测

(3)文件缓存的清理

(4)网络文件结构显示及管理,如ftp、云盘等

2.2 开发相关性分析

这里列举一下文件存储需要考虑的问题或者开发遇到的问题,后面接口检查的时候看是否能解决到此类问题。

(1)FileUtil.java帮助类大量重复;IOS可能不需要

(2)资源文件或者配置文件的本地存储,目录比较混乱清理资源的时候清理不全

(3)特定的业务,如加解密,解压等,有公共的接口

(4)不同账户登陆管理的文件不同

(5)文件的可操作等级不同,临时文件,可删除文件,不可删除文件;

(6)做到对上层透明, 跨平台化,IOS 跟 android 不再有沙盒跟sd卡的区分。

2.3 Android存储分析

Android手机上的存储空间可做如下划分:

● 内存:RAM

● 内部存储:内部ROM

● 外部存储:外部ROM和SDCard

(1)文件目录含义

android目录结构
android目录结构

data文件夹:内部都是app的包名,存储着应用程序相关的数据,例如 data/data/包名/(shared_prefs、database、files、cache);

mnt文件夹: 是Unix/Linux系统下外部设备的专用目录,Linux默认挂载外部设备都会挂载到这个目录;如将SD卡挂载后,会生成目录:/mnt/sdcard/.

sdcard文件夹:这个文件夹中的文件又分为两类,一类是公有目录,还有一类是私有目录,其中的公有目录有九大类,比如DCIM、DOWNLOAD等这种系统为我们创建的文件夹,私有目录就是Android这个文件夹,这个文件夹打开之后里边有一个data文件夹,打开这个data文件夹,里边有许多包名组成的文件夹。

如果按照路径的特征,我们又可以将文件存储的路径分为两大类,一类是路径中含有包名的,一类是路径中不含有包名的,含有包名的路径,因为和某个App有关,所以对这些文件夹的访问都是调用Context里边的方法,而不含有包名的路径,和某一个App无关,我们可以通过Environment中的方法来访问。如下图:

目录描述
目录描述

注意上述最后两个API:当app被卸载后,sdCard/Android/data/PackageName/下的所有文件都会被删除,不会留下垃圾信息。两个API对应的目录分别对应着 设置->应用->应用详情里面的“清除数据”与“清除缓存”选项。

2.4 IOS存储分析

IOS 沙盒提供不同的目录保存不同需求的文件,如是否备份云端,是否永久保存。

(1).Documents:

  用户生成的文件、其他数据及其他程序不能重新创建的文件,iTunes备份和恢复的时候会包括此目录。

(2).Library/Caches:

  可以重新下载或者重新生成的数据,数据库缓存文件和可下载内容应该保存到这个文件夹,iTunes不会备份此目录,此目录下文件不会在应用退出删除。

(3).tmp

  只是临时使用的数据,iTunes不会备份和恢复此目录,此目录下文件可能会在应用退出后删除。

2.5 跨平台上的考虑

Android和IOS的存储结构不一致,作为跨平台的接口,我们需要在目录结构分配的时候针对不同平台做相应的划分。根据两个平台存储的方式,我们在接口上应该做相应的抽象,将可操作的目录根据含义划分。

3.设计

3.1 设计目的

文件服务的根本目的是为APP提供统一、简洁、方便的文件操作的接口,为不同业务应用服务。

3.2 总体结构

这里看下本模块在整体构架中的位置,并简要描述本模块与周边系统的交互关系(如依赖方向、通信手段等);

● 物理文件。

分为本地文件和云端文件,不同平台上物理文件的权限不一样。

● 文件服务的设计。

(1)基本文件操作;

提供基本的文件的接口的实现,如创建、删除、移动、拷贝等。

(2)虚拟文件系统;

抽象出一个虚拟的文件系统的概念,即将一块空间或者某个目录结构当成一块完整的物理空间,对此我们进行管理划分,我们要做的比如,目录分配、目录映射、目录删除及对外提供接口。

(3)文件管理服务;

在这个层次上,我们还需要对文件管理服务做一个生命周期的管理、对现有虚拟文件的一些索引信息进行保存或者管理。

业务模块。

对外接入的一些业务。

结构描述
结构描述

3.3 接口设计

(1)文件服务调用的基本流程

流程图
流程图

(2)接口类关系

类关系
类关系

这里IFileService使用了IFileSystem的接口,IFileSystem最为一个抽象的文件系统,可以是本地的文件,也可能是远程文件,还可能是zip或者jar这种一块物理存储区域。只要实现了我们的这些接口均可以通用。

(3)接口设计及含义

详见 https://git.code.oa.com/rabbit/IdlTools/tree/master/idl_file/File

(1)IRAFileService

接口名

含义

createFileSystem

创建虚拟文件系统

(1)IRAFileSystem

接口名

含义

init

*初始化文件系统*@path 初始化路径,具体由文件系统实现定义。*@return 初始化成功返回true, 否则返回false。

uninit

反初始化

delete

删除该文件系统

openFile

#打开一个文件 #@return 具体文件的接口,其实质是具体文件的句柄。

setExtraParam

#针对特殊文件系统的特殊参数设置,具体取值参考文件系统实现文档。 #网络文件系统,可以通过此参数设置认证用的token。 打包文件系统可以用此接口设置打开包所需要的密码。

(2)IRAFile

接口名

含义

create():bool;

#在此文件路径位置创建一个空文件。 #文件存在时候强制覆盖原来的文件。 #@return 如果成功则返回true, 失败则返回false。

delete():bool;

#删除此文件路径的文件。 #@return 成功则返回true, 失败则返回false。

exists():bool;

#测试此路径名表示的文件或目录是否存在。

makedir():bool;

#在当前位置创建文件夹。

copy(destPath:string):bool;

#将此文件copy到指定位置 #如果目标位置已经存在文件则直接覆盖。 #如果此是目录,则直接返回失败。 #@return 如果拷贝成功则返回true, 否则返回false

move(destPath:string):bool

#将此文件、目录移动到目标位置,如果目标位置已经存在文件则直接覆盖。 #@return 如果移动成功则返回true, 否则返回false

getPath():string;

#Path()文件的绝对路径。 #如果是目录,最后不包含斜杠。

getParent():string;

#返回此路径名的父路径名的抽象路径名 #返回值最后不包含斜杠 #如果此路径名没有指定父目录,则返回 null。

getName():string;

#返回由此文件或目录的名称。

size():i64;

#文件大小 #@return 返回文件的体积

listFiles():list<IRAFile>;

#返回一个文件数组, #这些路径名表示此抽象路径名所表示目录中的文件。 #如果是一个文件,则返回NULL。

isDirectory():bool;

#判断是一个文件还是一个目录。 #@return 如果是一个目录则返回True,否则返回False。

readAllBytes():binary;

#读取文件的二进制内容。 #打开文件,并将文件内容以二进制返回, 之后关闭文件。 #如果文件读取失败, 或此文件是一个目录则返回一个NULL。

writeAllBytes(data:binary):bool;

#将二进制数据写入文件。 #打开文件,并将data对应的二进制数据写入文件, 之后关闭文件。 #写入成功后,文件的原内容将被覆盖。 #如果写入文件失败,则返回false, 否则返回true。

getCreateTime():i64;

#获取文件的创建时间。(自1970年1月1日午夜起的毫秒数) #@return 文件的创建时间,如果没有创建时间则返回-1。

getLastModifiedTime():i64;

#获取文件的修改时间。(自1970年1月1日午夜起的毫秒数) #@return 文件的修改时间,如果没有修改时间则返回-1。

getLastAccessTime():i64;

#获取文件的访问时间。(自1970年1月1日午夜起的毫秒数) #@return 文件的访问时间,如果没有访问时间则返回-1。

openFileSteam():IRAFileStream;

#打开一个文件流 #@return 返回所打开的文件流,如果失败则返回NULL。

(3)IRAFileStream

接口名

含义

read(readBuffer: binary, readSize:i64):i64;

#从当前位置将文件的二进制内容读取到readBuffer中。 #@readBuffer 存储读取数据的buffer。 #@readSize 需要读取的二进制数据的大小。 #@return 实际读取到的大小, 如果文件到达末尾则返回-1

write(dataToWrite:binary, writeSize:i64):i64;

#从当前位置将data写入到文件中。 #@dataToWrite 存放要写入的数据缓存。 #@writeSize 需要写入的二进制数据大小。 #@return 实际写入的二进制数据的大小,如果无法写入则返回-1

seek(pos:i64, origin:RASeekOrigin):i64;

#移动当前文件指向的位置 #@pos 移动的位置 #@origin 相对于哪里开始移动。 #@return 相对于 origin 参数的字节偏移量

size():i64;

#@return 文件的大小

tell():i64;

#@return 返回当前文件指向的位置

close();

#关闭这个文件流

3.4 虚拟文件元数据探讨

一般虚拟文件系统主要分为两部分,一部分为元数据(metadata),另一部分为数据本身。元数据,是“包含了与数据有关信息的数据”,比如文件属性、文件时间戳等。这里我们操作的是实在的物理文件数据本身,所以元数据本身就存在这个文件的属性里面,我们不在额外设计。

我们用设计好的目录结构简单的来管理当前虚拟文件。

4.方案对比

4.1 Flutter文件系统设计

Flutter 文件系统只要分为两部分, path_provider.dart 管理App的目录,file.dart实现对文件的读写,下面以IOS为例:

目录接口名

含义

getTemporaryDirectory()

对应沙盒Tmp目录

getApplicationDocumentsDirectory()

对应沙盒Document目录

主要文件操作接口名

含义

open/openRead/openWrite

打开一个文件, 读写, 只读, 写

writeAsByte/writeAsString

写文件

readAsByte/readAsString

读文件

create

创建一个文件

rename

重命名一个文件

copy

拷贝一个文件

length

获取文件的大小

get/set_LastAccessed

获取或设置文件的最后访问时间

get/set_LastModified

获取或设置文件的最后访修改时间

特点

1、跨平台,使用方不需要考虑具体设备系统。

2、文件操作接口都实现了同步跟异步。

https://docs.flutter.io/flutter/dart-io/File-class.html

FileMode

https://docs.flutter.io/flutter/dart-io/FileMode-class.html

4.2 Unity3D文件管理相关的接口设计

https://docs.unity3d.com/ScriptReference/30_search.html?q=file

https://docs.unity3d.com/ScriptReference/Windows.File.html

引擎的API中File类的接口

Directory类

脚本编辑器用的C#

https://docs.microsoft.com/zh-cn/dotnet/api/system.io.file?redirectedfrom=MSDN&view=netframework-4.7.2

特点:

(1)引擎公开的api接口简单,包括读、写和删除,接口封装成了“文件”和“目录”两个类抽象类来管理,都是同步操作;

(2)编辑器用的是.NET Framework的文件管理,文件管理接口非常丰富

读、写、拷贝、移动、加解密等,同步操作;用属性的目录映射不同平台的文件夹,几乎是跨平台接口的标准做法;

Android平台

Application.dataPath : /data/app/xxx.xxx.xxx.apk

Application.streamingAssetsPath : jar:file:///data/app/xxx.xxx.xxx.apk/!/assets

Application.persistentDataPath : /data/data/xxx.xxx.xxx/files

Application.temporaryCachePath : /data/data/xxx.xxx.xxx/cache

IOS平台

Application.dataPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data

Application.streamingAssetsPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw

Application.persistentDataPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents

Application.temporaryCachePath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches

4.3 Android源码中文件管理相关的接口设计

Context.java中的文件相关接口https://developer.android.com/reference/android/content/Contex

接口
接口

特点:

(1)在Context中的文件操作类基本是读出,得到目录或者文件列表两个操作;

(2)基本上都是以文件为对象返回;

在看下JDK中文件对象的接口设计

http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

特点:

(1)文件对象类只有文件新建删除,列出文件,新建目录等操作,读写放到其他的类中,都是同步,异步接口放到NIO的包中;

4.3 小结

(1)我们这里虚拟文件基本上只是用来管理目录,复杂的读写可以交给不同平台具体去操作;我们保证新建和获取文件系统的接口,帮助分配目录空间;

(2)是否要做异步的接口,我们这里可将其作为后续先扩展;

(3)用属性的目录映射不同平台的文件夹,几乎是跨平台接口的标准做法;

(4)是否需要listRoot这个操作可以交给各个系统获取到了目录之后自己操作;

5.对性能需求的实现分析

(1)同步操作,交给上层进行异步处理;

(2)整个操作属于代理的工作无效率和内存问题

6.异常处理

这里的文件操作接口,不涉及具体的读写的话,可以不用抛出异常

7.参考资料

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 概述
    • 1.1 应用模块
      • 1.2 开发背景
        • 1.3 术语
    • 2.调研分析
    • 2.1 基本目标
    • 2.2 业务相关性分析
    • 2.2 开发相关性分析
    • 2.3 Android存储分析
    • 2.4 IOS存储分析
      • (1).Documents:
        • (2).Library/Caches:
          • (3).tmp
          • 2.5 跨平台上的考虑
          • 3.设计
          • 3.1 设计目的
          • 3.2 总体结构
            • ● 物理文件。
              • ● 文件服务的设计。
                • (1)基本文件操作;
                • (2)虚拟文件系统;
                • (3)文件管理服务;
            • 3.3 接口设计
            • 3.4 虚拟文件元数据探讨
            • 4.方案对比
              • 4.1 Flutter文件系统设计
                • 4.2 Unity3D文件管理相关的接口设计
                  • 4.3 Android源码中文件管理相关的接口设计
                    • 4.3 小结
                    • 5.对性能需求的实现分析
                    • 6.异常处理
                    • 7.参考资料
                    相关产品与服务
                    文件存储
                    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档