2

我是 python 新手,所以这可能最终有一个简单的解决方案。

在我家,我有 3 台与这种情况相关的电脑: - 文件服务器 (linux) - 我的主电脑 (windows) - 女朋友的 MacBook Pro

我的文件服务器正在运行 ubuntu 和 samba。我已经安装了 python 3.1,并在 3.1 中编写了我的代码。

我创建了一个守护进程,它确定上传目录中何时存在遵循给定模式的某些文件。找到此类文件后,它会对其进行重命名并将其移动到不同驱动器上的不同位置。它还重写了所有者、组和权限。所有这一切都很好。它每分钟运行一次这个过程。

如果我从我的主 PC 复制文件(运行 Windows 风格),该过程总是有效的。(我相信 Windows 会锁定文件直到它完成复制——我可能是错的。)如果我的女朋友复制一个文件,它会在复制完成之前拿起文件,事情变得一团糟。(创建了具有不正确权限的文件的下划线版本,有时文件会进入正确的位置)我在这里猜测她的mac book在复制时没有锁定文件。我在那里也可能是错的。

我需要的是一种方法来排除正在使用或正在创建的文件。

作为参考,我创建的查找文件的方法是:

# _GetFileListing(filter)
# Description: Gets a list of relevant files based on the filter
#
# Parameters: filter - a compiled regex query
# Retruns:
#   Nothing. It populates self.fileList
def _GetFileListing(self, filter):
    self.fileList = []
    for file in os.listdir(self.dir):
        filterMatch = filter.search(file)
        filepath = os.path.join(self.dir, file)

        if os.path.isfile(filepath) and filterMatch != None:
            self.fileList.append(filepath)

请注意,这都在一个类中。

我创建的用于操作文件的方法是:

# _ArchiveFile(filepath, outpath)
# Description: Renames/Moves the file to outpath and re-writes the file permissions to the permissions used for
#   the output directory. self.mask, self.group, and self.owner for the actual values.
#
# Parameters: filepath - path to the file
#             outpath - path to the file to output
def _ArchiveFile(self, filepath, outpath):
    dir,filename,filetype = self._SplitDirectoryAndFile(outpath)

    try:
        os.makedirs(dir, self.mask)
    except OSError:
        #Do Nothing!
        dir = dir

    uid = pwd.getpwnam(self.owner)[2]
    gid = grp.getgrnam(self.group)[2]
    #os.rename(filepath, outpath)
    shutil.move(filepath, outpath)
    os.chmod(outpath, self.mask)
    os.chown(outpath, uid, gid)

我已经停止使用 os.rename 因为当我开始将文件移动到不同的驱动器时它似乎已经停止工作。

简短版:如何防止自己在搜索中拾取当前正在传输的文件?

提前感谢您提供的任何帮助。

4

3 回答 3

0

结果写锁定方法不起作用。我想我在这里更新之前没有正确测试它。

我现在决定做的是:

  • 将检查之间的时间缩短到 30 秒
  • 保留在上一次迭代中找到的文件列表及其各自的文件大小
  • 对照旧列表检查新的文件列表

如果新列表包含与旧列表相同文件大小的相同文件,则将其放入要传输的列表中。新列表中的剩余文件将成为旧列表并继续该过程。

我确定 lsof 方法会起作用,但我不确定如何在 python 中使用它。此外,这种方法应该适用于我的情况,因为我最关心的是在传输过程中不移动文件。

我还必须排除所有以“._”开头的文件,因为 mac 会创建这些文件,我不确定它们是否会随着时间的推移而增加。

或者,我可以选择仅处理由她的 mac 传输的情况。我知道当mac传输文件时,它会创建:

  • 文件名.ext
  • ._filename.ext

我可以检查以 ._ 开头的所有文件名实例的列表,并以这种方式排除文件。

我可能会先尝试第二个选项。它有点脏,但希望它会起作用。

于 2010-11-08T21:08:11.850 回答
0

mac 中的 ._ 文件包含资源分叉。更多信息可以在这里找到:http: //support.apple.com/kb/TA20578

我没有足够的代表发表评论,因此答案。

在大多数情况下,您可以放心地忽略它们,因为无论如何其他操作系统都无法对它们做任何事情。更多关于它们的信息: http ://en.wikipedia.org/wiki/Resource_fork

于 2010-11-08T21:18:25.053 回答
0

您可以在移动文件之前尝试对文件进行独占写入锁定。这可以通过 fcntl 模块完成:

http://docs.python.org/library/fcntl.html

除此之外,您可以使用该lsof实用程序查看系统已打开的文件。这需要更多的苦差事。

请注意, os.rename() 将在同一个文件系统上工作,并且实际上不受这个问题的影响(inode 被移动,没有数据被移动)。使用 shutil 将照常使用mv,如果文件系统相同,则重新链接文件,如果文件系统不同,则复制 + 删除。

于 2010-11-05T22:43:01.123 回答