以下图片是ImageShack上托管的1000 x 750 px, ~130 kB JPEGs
。
我应该提到每个用户(客户端盒子)将直接在/Foo
份额下工作。由于业务的性质,用户永远不需要同时查看或处理彼此的文档,因此这种性质的冲突永远不会成为问题。访问需要尽可能简单,这可能意味着将驱动器映射到各自的/Foo/username
子目录。
此外,除了我的应用程序(内部和服务器上的应用程序)之外,没有人会直接使用FTP目录。
不幸的是,看起来我不能使用现成的工具,例如WinSCP,因为其他一些逻辑需要与流程密切相关。
我认为有两种简单的方法让我在内部完成上述工作。
方法一(慢):
每N分钟走一次/Foo
目录树。
使用时间戳的组合(可以通过文件复制工具伪造,但在这种情况下不相关)和校验和来与前一棵树进行差异。
将更改与异地FTP服务器合并。
方法二:
注册目录更改通知(例如,使用WinAPI中的ReadDirectoryChangesW
,或使用.NET时使用FileSystemWatcher
。
记录更改。
每隔N分钟与异地FTP服务器合并更改。
由于性能方面的考虑,我可能最终会使用第二种方法。
由于此同步必须在工作时间进行,因此出现的第一个问题是在场外上传阶段。
当我在异地传输文件时,我实际上需要阻止用户写入文件(例如,当我正在阅读时,使用CreateFile
和FILE_SHARE_READ
或其他内容)它。他们办公室的互联网上行速度与他们正在使用的文件大小几乎没有对称,所以他们很可能会回到文件并尝试修改它,而我还在阅读它。 / p>
解决上述问题的最简单方法是在文件系统的其他位置创建相关文件的副本,并在不受干扰的情况下传输这些“快照”。
这些人将使用的文件(有些将是二进制文件)相对较小,可能≤20MB,因此复制(因此暂时锁定)它们几乎是即时的。他们在我复制它的同一瞬间尝试写入文件的机会应该接近于零。
这个解决方案看起来有点难看,而且我很确定有更好的方法来处理这类问题。
我想到的一件事就是文件系统过滤器,它负责IRP级别的复制和同步,就像一些A / V所做的那样。然而,这对我的项目来说太过分了。
这是我第一次遇到这类问题,所以也许我在考虑太多了。
我对干净的解决方案感兴趣,这些解决方案不需要过多地实现其复杂性。也许我错过了WinAPI中优雅处理这个问题的东西?
我还没有决定我会写什么,但我很满意:C,C ++,C#,D和Perl。
答案 0 :(得分:1)
在评论中讨论后,我的建议就是这样:
所以基本上你有你的驱动器:
C:
Windows安装D:
分享存储X:
临时分区然后你会有以下服务:
LocalMirrorService
- 观看D:
并使用dir结构复制到X:
TransferClientService
- 将文件从X:
移至ftp服务器,从X:
移除
我敢打赌,这是你想到的想法,但这似乎是一种合理的方法,只要你的应用程序开发非常好,并且你能够创建一个可以处理大多数问题的可靠系统。
例如,当用户在Microsoft Word中编辑文档时,该文件将在共享上更改,并且可能会将其复制到X:
,即使用户仍在使用它,在Windows中也会有API查看文件句柄是否仍由用户打开,如果是这种情况,那么您可以创建一个钩子,以便在用户实际关闭文档时进行监视,以便完成所有编辑,然后您可以迁移到驱动器{{1 }}
这就是说,如果用户正在处理文档并且由于某种原因PC崩溃,则文档/文件句柄可能不会在以后打开文档时释放,从而导致问题。
答案 1 :(得分:0)
对于处于类似情况的任何人(我假设很久以前问过该问题的人实施了解决方案),我建议实施rsync。
rsync.net的Windows Backup Agent执行方法1中描述的操作,也可以作为服务运行(请参阅“Advanced Usage”)。虽然我不完全确定它是否内置带宽限制......
具有带宽限制的另一个(可能更好)解决方案是Duplicati。它还可以正确备份当前打开或锁定的文件。对其后端使用SharpRSync,一种托管的rsync实现。开源也是,这总是一个加号!