代码之家  ›  专栏  ›  技术社区  ›  Dan Vinton

检测传输中的文件?

  •  2
  • Dan Vinton  · 技术社区  · 16 年前

    我正在编写一个应用程序,通过每隔几秒钟轮询一次目录来监视目录中的新输入文件。新文件通常可能有几兆字节,因此需要一些时间才能完全到达输入目录(例如:从远程共享复制)。

    是否有一种简单的方法来检测文件当前是否正在被复制?理想情况下,任何方法都是平台和文件系统无关的,但如果做不到这一点,可能需要为不同的平台制定特定的策略。

    我已经考虑过将两个目录列表分开几秒钟并比较文件大小,但这会带来时间/可靠性的权衡,除非别无选择,否则我的上级不会满意。

    作为背景,该应用程序是作为一组Matlab M文件编写的,所以恐怕没有JRE/CLR技巧。..


    编辑: 文件通过直接移动/复制操作直接从网络驱动器或本地文件系统上的另一个位置到达输入。此复制操作可能由人类用户而不是其他应用程序启动。

    因此,很难让文件提供者承担添加控制文件或使用中间暂存区的任何责任。..


    结论: 似乎没有简单的方法可以做到这一点,所以我决定采用皮带和牙套的方法——如果满足以下条件,文件就可以处理了:

    • 其大小在特定时间段内不会改变,
    • 可以以只读模式打开文件(某些复制过程会对文件进行锁定)。

    感谢大家的回复!

    5 回复  |  直到 16 年前
        1
  •  7
  •   Michael Borgwardt    16 年前

    最安全的方法是让将文件放在目录中的应用程序首先将它们放在另一个临时目录中,然后将它们移动到真实的目录中(即使使用FTP或文件共享,这也应该是一个原子操作)。您还可以使用命名约定在一个目录中实现相同的结果。

    编辑: 这实际上取决于文件系统,取决于其复制功能是否具有“完整文件”的概念。我不太了解SMB协议,但如果它有这个概念,您可以编写一个应用程序,公开SMB接口(或修补Samba)和API,以获得完成文件副本的通知。但可能要做很多工作。

        2
  •  3
  •   Martin Cowie    16 年前

    这是一个由来已久的中间件问题,简短的回答是:没有。

    这两种“解决方案”将责任放在文件上传者身上:(1)将文件上传到暂存目录中,然后将其移动到目标目录中;(2)上传文件,然后创建/上传一个指示内容文件状态的“就绪”文件。

    第一个更好,但两者都不优雅。事实是,存在比文件系统更好的通信介质。考虑使用一些只涉及推送或拉取(而不是像文件系统那样同时涉及两者)的IPC,如HTTP POST、JMS或MSMQ队列等。此外,这也可以是同步的,允许接收文件的进程确认内容,甚至检查其价值,并向客户端发送收据——这是实现不可否认性的正义之路。遵循以下步骤,您将永远不会因为文件是否被传递到服务器进行处理而受到争论。

    M

        3
  •  1
  •   Bork Blatt    16 年前

    一种简单的可能性是以相当大的间隔(2到5分钟)进行轮询,并在第二次看到新文件时才确认。

    我不知道在任何操作系统中,除了检查文件是否被锁定外,还有什么方法可以确定文件是否仍在被复制。

        4
  •  1
  •   benlumley    16 年前

    文件是如何到达那里的?你能在它们被写入时设置一个属性,然后在写入完成时更改属性吗?这需要通过写作来完成。..听起来这不是一个选择。

    否则,缓存列表并将连续两个列表具有相同文件大小的文件视为新文件是我能想到的最好方法。

    或者,您可以使用文件上的修改时间——文件必须是新的,并且修改时间至少是过去的x。但我认为这相当于缓存列表。

    如果你每隔几秒钟就轮询一次文件夹,这不会造成太大的时间损失,是吗?而且它与平台无关。

    此外,仅限linux: http://www.linux.com/feature/144666

    类似于cron,但用于文件。不确定它是如何处理你的具体问题的,但可能有用?

        5
  •  0
  •   James Anderson    16 年前

    你的操作系统是什么。在unix中,您可以使用“lsof”实用程序来确定用户是否已打开文件进行写入。显然,在MS Windows Process Explorer的某个地方也有相同的功能。

    或者,你可以尝试对文件进行独占打开,但退出失败。但这可能有点不可靠,很容易踩到自己的脚趾。

    推荐文章