迭代文件系统子树的快照 [英] Iterator over a snapshot of a filesystem subtree

查看:123
本文介绍了迭代文件系统子树的快照的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Java中的文件系统子树上开发一个迭代器。在迭代仍在进行时,文件系统的状态可能会发生变化(例如,创建和删除新文件夹和文件)。因此,迭代器应首先捕获层次结构的快照(例如,抓取树并保存找到的所有文件的名称),然后迭代快照。

I need to develop an iterator over a filesystem subtree in Java. The state of the filesystem might change while the iteration is still in progress (e.g. new folders and files get created and deleted). The iterator should therefore first capture a snapshot of the hierarchy (e.g. crawl the tree and save the names of all files found to a list) and then iterate over the snapshot.

我想知道将代码放入迭代器的构造函数中是否是一个好主意。另一种方法是为其指定一个特殊方法(名为 init )。

I am wondering if it is a good idea or not to put the code to create the cache into the iterator's constructor. An alternative would be to designate a speciall method for that (named init).

迭代子树的大小和深度可能会非常大,因此缓存将非常耗时。此外,它可能抛出IOExceptions(我仍然不确定在Java中从构造函数中抛出异常是否是一个好的设计实践)。

The size and depth of the iterated subtree might get quite large and the caching will therefore be time consuming. Moreover, it might throw IOExceptions (I am still not sure if it is good design practice to throw exceptions from constructors in Java).

另一方面,创建一个专用的初始化迭代器的方法意味着客户端代码不能将迭代器简单地用作Iterator接口的实现。

On the other hand, creating a dedicated method to initialize the iterator would mean the client code could not use the iterator as simply an implementation of the Iterator interface.

客户端代码也将负责调用init遍历之前的方法。我可以让 hasNext / next 方法首先确保迭代器已经初始化,如果没有,请调用 init 来自其中的方法。但这意味着对这些方法的第一次调用将明显慢于下一次调用,而客户端没有任何理由可见。

The client code would also be responsible for calling the init method prior to the traversal. I could have the hasNext/next methods first make sure that the iterator has been initialized and if not, call the init method from within them. But that would mean the first call to these methods would be significantly slower than the next ones without any reasons visible from the client side.

推荐答案

<正如你在评论中所说,我会把责任分成两类:一类用于获取文件系统的快照(例如 FileSystemSnapshot ),另一类用于迭代它。根据您需要的灵活性,您可以在迭代器的构造函数中创建 FileSystemSnapshot 实例,或将其作为构造函数参数传递。从第一个方向开始,客户端可以更灵活地配置迭代器,如果您计划采用不同的策略来获取文件系统快照,则可能很有价值。它也更适合单元测试,因为很容易创建模拟或存根。但是,您强制客户端了解遍历详细信息(即,在遍历文件系统之前必须缓存文件系统)。使用第二种方法从客户端隐藏了这个实现细节,但是不太灵活,测试起来有点棘手(这里你可以定义一个 createFileSystemSnapshot()方法,然后模拟为测试返回不同实例的方法)。您可能还想查看依赖注入模式。

As you said in the comments, I would go for separating the responsibilities in two classes: one for taking the snapshot of the file system (e.g FileSystemSnapshot) and one for iterating it. Depending on the flexibility you need, you can create the FileSystemSnapshot instance in the constructor of the iterator or pass it as a constructor argument. Going in the first direction gives the client more flexibility to configure the iterator and can be valuable if you are planning to have, for example, different strategies for taking file system snapshots. It is also better for unit testing, since it is easy to create mocks or stubs. However, you are forcing the client to know about the traversal details (i.e. that the file system has to be cached before traversing it). Using the second approach hides this implementation details from the client, but is less flexible and a little bit trickier to test (here you could define a createFileSystemSnapshot() method and then mock that method to return a different instance for your tests). You may also want to check the dependency injection pattern.

HTH

这篇关于迭代文件系统子树的快照的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆