Производительность программы чтения файловой системы Python - PullRequest
0 голосов
/ 14 марта 2012

Мне нужно просканировать файловую систему на наличие списка файлов и записать в журнал тех, кто не существует.В настоящее время у меня есть входной файл со списком из 13 миллионов файлов, которые необходимо исследовать.Этот сценарий необходимо запускать из удаленного местоположения, поскольку у меня нет доступа / я не могу запускать сценарии непосредственно на сервере хранения.

Мой текущий подход работает, но относительно медленный.Я все еще довольно плохо знаком с Python, поэтому я ищу советы по ускорению.

import sys,os
from pz import padZero #prepends 0's to string until desired length
output = open('./out.txt', 'w')
input = open('./in.txt', 'r')
rootPath = '\\\\server\share\' #UNC path to storage
for ifid in input:
    ifid = padZero(str(ifid)[:-1], 8) #extracts/formats fileName
    dir = padZero(str(ifid)[:-3], 5) #exracts/formats the directory containing the file
    fPath = rootPath + '\\' + dir + '\\' + ifid + '.tif'
    try:
        size = os.path.getsize(fPath) #don't actually need size, better approach?
    except:
        output.write(ifid+'\n')  

Спасибо.

Ответы [ 4 ]

1 голос
/ 14 марта 2012
dirs = collections.defaultdict(set)

for file_path in input:
    file_path = file_path.rjust(8, "0")
    dir, name = file_path[:-3], file_path

    dirs[dir].add(name)

for dir, files in dirs.iteritems():
    for missing_file in files - set(glob.glob("*.tif")):
        print missing_file

Объяснение

Сначала прочитайте входной файл в словарь каталога: filename.Затем для каждого каталога перечислите все файлы TIFF в этом каталоге на сервере и (установите) вычтите это из набора имен файлов, которые вы должны иметь.Напечатайте все, что осталось.

РЕДАКТИРОВАТЬ: Исправлены глупые вещи.Слишком поздно ночью, когда я написал это!

0 голосов
/ 14 марта 2012

Я бы, вероятно, использовал команду оболочки, чтобы получить полный список файлов во всех каталогах и подкаталогах одним ударом.Надеемся, что это сведет к минимуму количество запросов на сервер.

Вы можете получить список файлов удаленного сервера, выполнив что-то вроде:

  • Linux: mount общий диск как /shared/directory/, а затем введите ls -R /shared/directory > ~/remote_file_list.txt
  • Windows: используйте Map Network Drive, чтобы подключить общий диск как букву диска X:, затем выполните dir /S X:/shared_directory > C:/remote_file_list.txt

Используйте те же методы для создания списка содержимого вашей локальной папки, что и local_file_list.txt.Затем ваш скрипт на python сведется к упражнению по обработке текста.

Примечание: на самом деле мне пришлось сделать это на работе.

0 голосов
/ 14 марта 2012

Мне кажется, что вещи с падзером и конкатенацией строк заняли бы хороший процент времени.

То, что вы хотите, это потратить все свое время на чтение каталога, совсем немного.

Вы должны сделать это на python? Я делал подобные вещи в C и C ++. Java тоже должна быть довольно хорошей.

0 голосов
/ 14 марта 2012

Вы будете привязаны к вводу / выводу, особенно в сети, поэтому любые изменения, которые вы можете внести в свой скрипт, приведут к очень минимальным ускорениям, но не в моей голове:

import os

input, output = open("in.txt"), open("out.txt", "w")

root = r'\\server\share'

for fid in input:
    fid  = fid.strip().rjust(8, "0")
    dir  = fid[:-3]      # no need to re-pad
    path = os.path.join(root, dir, fid + ".tif")
    if not os.path.isfile(path):
        output.write(fid + "\n")

Я не ожидаю, что это будет быстрее, но, возможно, его легче читать.

Другие подходы могут быть быстрее.Например, если вы ожидаете прикоснуться к большинству файлов, вы можете просто получить полный рекурсивный список каталогов с сервера, преобразовать его в Python set() и проверить его на членство, а не попадать на сервер для множества небольших запросов.,Я оставлю код в качестве упражнения ...

...