2010-11-05 5 views
2

Je suis novice en python, donc cela pourrait avoir une solution simple.Comment exclure des fichiers d'une recherche en cours d'utilisation ou en cours de copie dans python?

Chez moi, j'ai 3 ordinateurs qui sont pertinents à cette situation: - File Server (Linux) - Mon principal PC (Windows) - MacBook Pro

Girlfriend Mon serveur de fichiers est en cours d'exécution ubuntu et samba. J'ai installé python 3.1 et j'ai écrit mon code en 3.1.

J'ai créé un démon qui détermine quand certains fichiers existent dans le répertoire des téléchargements qui suivent un modèle donné. En trouvant un tel fichier, il le renomme et le déplace vers un emplacement différent sur un lecteur différent. Il réécrit également le propriétaire, le groupe et les autorisations. Tout cela fonctionne très bien. Il exécute ce processus chaque minute.

Si je copie des fichiers à partir de mon ordinateur principal (en exécutant une saveur de Windows), le processus fonctionne toujours. (Je crois que Windows verrouille le fichier jusqu'à ce qu'il soit copié - Je peux me tromper.) Si ma copine copie un fichier, il récupère le fichier avant que la copie ne soit terminée et les choses deviennent compliquées. (des versions soulignées des fichiers avec des permissions incorrectes sont créées et parfois, le fichier ira au bon endroit) Je devine ici que son livre mac ne verrouille pas le fichier lors de la copie. Je pourrais aussi me tromper là-bas.

Ce dont j'ai besoin, c'est d'un moyen d'exclure les fichiers en cours d'utilisation ou, à défaut, en cours de création.

Pour référence, la méthode que j'ai créé pour trouver les fichiers est:

# _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) 

Remarque, cela est dans une classe.

La méthode que j'ai créé pour manipuler les fichiers est:

# _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) 

J'ai cessé d'utiliser os.rename parce qu'il semble avoir cessé de travailler quand j'ai commencé à déplacer des fichiers différents lecteurs.

Version abrégée: Comment puis-je m'empêcher de récupérer des fichiers dans ma recherche en cours de transfert?

Merci d'avance pour toute aide que vous pourriez être en mesure de fournir.

Répondre

0

Il s'avère que l'approche de verrouillage en écriture n'a pas fonctionné. Je suppose que je n'ai pas testé correctement avant de mettre à jour ici.

Ce que j'ai décidé de le faire pour l'instant est:

  • Réduire le temps entre les contrôles à 30 ans
  • Gardez une liste des fichiers trouvés dans la itération précédente et leur fichier respectif tailles
  • Vérifier la nouvelle liste de fichiers par rapport à l'ancienne liste

Si la nouvelle liste contient le même fichier avec la même taille de fichier que l'ancienne lis t, le mettre dans une liste à transférer. Les fichiers restants dans la nouvelle liste deviennent l'ancienne liste et le processus se poursuit.

Je suis sûr que la méthode lsof fonctionnera mais je ne suis pas sûr de savoir comment l'utiliser en python. Aussi cette méthode devrait fonctionner assez bien pour ma situation puisque je suis surtout préoccupé par ne pas déplacer les dossiers pendant qu'ils sont en transit.

Je devrais également exclure tous les fichiers qui commencent par "._" car le mac les crée et je ne suis pas sûr qu'ils augmentent avec le temps.

Sinon, j'ai la possibilité de gérer les cas où elle est transférée par son mac. Je sais que lorsque le mac transfère le fichier, il crée:

  • filename.ext
  • ._filename.ext

je pouvais vérifier la liste de toutes les instances de nom de fichier où il est précédèrent avec ._ et exclure les fichiers de cette façon.

Je vais probablement essayer la deuxième option en premier. C'est un peu sale mais j'espère que ça va marcher.

+0

Après avoir essayé la deuxième méthode, je l'ai eu à travailler pour mes fins. Je voudrais souligner les choses suivantes que j'ai observées. Si vous copiez d'un mac vers un partage linux samba, il créera un fichier temp nommé ._filename. Cela peut être utilisé pour exclure le fichier de votre recherche. Si vous utilisez la méthode que j'ai répertoriée dans mon message d'origine pour déplacer le fichier, lorsque vous copiez un fichier à partir de Windows, l'application attendra que le transfert soit terminé, puis copiera le fichier. Si vous annulez le transfert de fichier, vous risquez de bloquer le processus (il se peut que je sois impatient et que le fichier soit trop volumineux ...) – Karoupa

0

Vous pouvez essayer de prendre un verrouillage d'écriture exclusif sur le fichier avant de le déplacer. Cela peut être fait avec le module fcntl:

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

Sauf que, vous pouvez nous l'utilitaire lsof pour voir les fichiers que le système a ouvert. Cela nécessite plus de corvée. Notez que os.rename() fonctionnera sur le même système de fichiers, et serait réellement immunisé à ce problème (l'inode est déplacé, aucune donnée n'est déplacée). Utiliser shutil fera comme le fait mv, qui est soit relier le fichier si c'est le même système de fichiers, soit copier + supprimer si les systèmes de fichiers sont différents.

+0

Merci pour la réponse. Je vais essayer le verrouillage d'écriture exclusif. J'espère que cela n'annule pas le transfert de fichiers. J'ai aussi entendu parler de la méthode lsof mais je n'ai pas trouvé de moyen de l'exécuter dans mon code python. – Karoupa

0

Les fichiers ._ du mac contiennent des liens de ressources. Plus d'informations peuvent être trouvées ici: http://support.apple.com/kb/TA20578

Je n'ai pas assez de représentant pour faire un commentaire, d'où la réponse. Pour la plupart, vous pouvez les ignorer en toute sécurité, car aucun autre système d'exploitation ne peut probablement faire quoi que ce soit avec eux. Plus d'informations sur eux ici: http://en.wikipedia.org/wiki/Resource_fork

+0

Neat. De toute façon, ils se sont révélés utiles dans mon cas. Je voudrais vous voter mais je n'ai pas assez de rep. – Karoupa

Questions connexes