观看网络目录时的pywintypes.error

时间:2013-07-01 23:16:34

标签: python watch network-drive

我的医疗办公室有一个网络驱动器(运行DLink-325 NAS,如果这有任何区别),它可以为我们的患者提供所有文件。每位患者都有一个名称相应的文件夹,每个文件夹都有这些文件。问题是Windows文件浏览器不适合这种情况 - 用户可能会意外地重命名文件夹(丢弃排序),移动患者文件夹等等。所以,我正在开发一个python应用程序(构建在django上用于Web界面)我需要确保django数据库与文件系统匹配,以便每当某些内容随文件/文件夹名称发生变化时,数据库指向正确的文件。我读了Tim Golden's article并认为这将是一个很好的解决方案。它就是 - 只要我在本地文件夹上测试它。但是,一旦我将其指向网络驱动器,我就遇到了这个奇怪的错误:

Traceback (most recent call last):   File "C:\projects\RecordKeeper\test.py", line 50, in <module>
    None pywintypes.error: (58, 'ReadDirectoryChangesW', 'The specified server cannot perform the requested operation.') [Finished in 16.4s]

奇怪的是,当文件名更改为新内容时,只会发生 。如果我更改文件名,然后将其更改回来,一切都会完美无缺。

例如,如果原始文件名是&#34; Referral.pdf&#34;然后我将其更改为&#34; Raferral.pdf&#34; (只是将&#34; e&#34;改为&#34; a&#34;),我收到错误。但是,如果我将其更改回&#34; Referral.pdf&#34;,我会得到正确的输出。这是我的代码(我已更改文件夹名称以保护患者健康信息):

import os

import win32file
import win32con

ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"
}
# Thanks to Claudio Grondi for the correct set of numbers
FILE_LIST_DIRECTORY = 0x0001

#path_to_watch = "C:\projects\working"
path_to_watch = "Z:\_Charts\Abruzzo, Sandra J - 1947-11-18"
hDir = win32file.CreateFile (
  path_to_watch,
  FILE_LIST_DIRECTORY,
  win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
  None,
  win32con.OPEN_EXISTING,
  win32con.FILE_FLAG_BACKUP_SEMANTICS,
  None
)
while 1:
  #
  # ReadDirectoryChangesW takes a previously-created
  # handle to a directory, a buffer size for results,
  # a flag to indicate whether to watch subtrees and
  # a filter of what changes to notify.
  #
  # NB Tim Juchcinski reports that he needed to up
  # the buffer size to be sure of picking up all
  # events when a large number of files were
  # deleted at once.
  #
  try:
    results = win32file.ReadDirectoryChangesW (
      hDir,
      1024,
      True,
      win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
       win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
       win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
       win32con.FILE_NOTIFY_CHANGE_SIZE |
       win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
       win32con.FILE_NOTIFY_CHANGE_SECURITY,
      None,
      None
    )
    for action, file in results:
      full_filename = os.path.join (path_to_watch, file)
      print full_filename, ACTIONS.get (action, "Unknown")
  except Exception as e:
    print "Unexpected error:", e

更新

我在上面的代码中添加了try / catch块来解决这个问题。似乎只是重命名的东西导致了问题。它仍然可以判断文件是否已更新。这是我在一次测试中得到的输出:

Z:\_Charts\Abruzzo, Sandra J - 1947-11-18\2013-06-12 Request for records.pdf Renamed from something
Z:\_Charts\Abruzzo, Sandra J - 1947-11-18\2013-06-12 Requeast for records.pdf Renamed to something
Z:\_Charts\Abruzzo, Sandra J - 1947-11-18\2013-06-12 Requeast for records.pdf Updated
Unexpected error: (58, 'ReadDirectoryChangesW', 'The specified server cannot perform the requested operation.')
Z:\_Charts\Abruzzo, Sandra J - 1947-11-18\2013-06-12 Request for records.pdf Updated

正如您所看到的,它处理了第一次重命名没有问题。但是当我尝试重命名它时,重命名操作引发了错误,但更新通知工作得很好。任何人都有这些新皱纹的想法吗?

更新

我想我已经找到了解决方案。正如许多用户所说,实际上从网络驱动器获取准确的数据并不会发生。但是,该程序至少每次更新文件时都会报告,即使它在获取重命名数据时出错也是如此。因此,我编写了几个通过数据库的特殊方法,找到了不再指向有效文件的记录,并更新了这些记录。希望能做到这一点。如果有人有更好的解决方案,请随时分享! :d

1 个答案:

答案 0 :(得分:1)

根据this blog,NAS设备通常不支持支持ReadDirectoryChangesW功能所需的功能,因此听起来问题在于您的驱动器,而不是您的python代码。这个accompanying page提到了其他一些提供类似功能及其各种优缺点的功能,但没有详细说明它们是否适用于网络驱动器。