我想为我的服务器上的文件夹结构创建一个web界面。基本上就像dropbox或任何其他云存储,但只有读取功能,不创建新文件或上传。
我想知道最好的方法是创建一个"虚拟的";我的服务器上现有文件夹结构的表示。
我的想法是递归地遍历服务器上的目录,并为每个文件或文件夹创建一个数据库条目。我将为每个文件创建一个散列,以唯一地标识它们。
:
'1382b6993e9f270cb1c29833be3f5750': {
type: 'folder',
name: 'root',
path: '/',
parentPath: null,
parentID: null,
children: ['147d0ef33fe657ce53a83de6a630473d']
},
'147d0ef33fe657ce53a83de6a630473d': {
type: 'folder',
name: 'pictures',
parentID: '1382b6993e9f270cb1c29833be3f5750',
parentPath: '/',
path: '/pictures',
children: ['8f7c5959dbb088c0aef8b145dbdf6e43']
},
'8f7c5959dbb088c0aef8b145dbdf6e43': {
type: 'file',
name: 'cat.jpg',
parentID: '147d0ef33fe657ce53a83de6a630473d',
parentPath: '/pictures',
path: '/pictures/cat.jpg'
},
为了解释目录的变化,我会定期运行一个进程来扫描它并相应地更新数据库。
应该说这个目录相当大,有许多子文件夹和数百个文件。
由于整个文件夹结构相当大,我可以看到它是一个问题,保持整个树在反应状态,但我想这可以通过总是抓取目录内容时,在前端导航修复。
这个方法有意义吗?还是有更好的方法?
您可以根据更方便的方式来优化磁盘使用情况或CPU使用情况。这最终只是两者之间的权衡。
如果您希望最大化CPU负载,并且知道磁盘空间很便宜,那么您可以像以前那样存储整个文件系统树表示的内容,并定期更新。主要的好处是,你将有一个非常小的CPU占用,如果你的应用程序是由许多用户使用,你的服务器不会被API请求过载。主要缺点是,当您需要定期更新文件系统树时,它会占用大量的CPU和磁盘使用,并且可能会出现同步问题(当文件已创建但未存储在数据库中时)。
在数据库方面,当数据之间几乎没有关系或者想要大规模地快速读取数据时,应该使用NoSQL数据库而不是SQL数据库来构建高只读目的的数据库。
如果您想坚持使用SQL数据库,您应该使用外键来存储父文件夹,例如在为文件创建数据库条目时,您可以做类似的事情。
INSERT INTO files(path, type, parent) VALUES("/home/johndoe", "FOLDER", 987126398726387)
其中987126398726387
将是与/home
文件夹相关的files
行的id
列。这样,您的对账文件夹的算法将非常简单,因为您只需要发出一个请求来检索文件夹中的所有文件。
SELECT * FROM files WHERE parent = 987126398726387;
你可以使用SQL的所有功能来排序,分组和做你可能想在那里做的事情。
您可以通过完全删除数据库并拥有一个类似https://api.com/folders/:tree
的单一API端点来交换磁盘使用,而不是加载磁盘使用,其中tree
是客户端请求的文件夹树。
例如,如果我启动应用程序,我可能想要请求https://api.com/folders/
端点,并且您可以只发送该文件夹的内容而不发送其子文件夹,从而消除了对递归算法的需要。然后,如果我需要进入/home
文件夹,我可以调用https://api.com/folders/home
端点。然后,我将在/home/johndoe
文件夹中添加https://api.com/folders/home/johndoe
,在/home/johndoe/code
文件夹中添加https://api.com/folders/home/johndoe/code
,等等…
您甚至可以将请求的路径传递到来自客户端的异步HTTP请求的正文中。
GET /folders HTTP/2
Host: api.com
Content-Type: application/json
{
"path": "/home/johndoe/code"
}
当API响应时,您可以在客户端更新当前文件夹时显示加载程序。这显然会产生更多的API调用,但这样做可以节省大量的磁盘使用。如果你需要速度或更少的CPU占用,你可以使用像V, Go或Rust这样的编译语言来实现,并创建一个微服务,其唯一目的是快速获取文件夹的内容。