2012-01-22 26 views
7

Próbuję przeskanować mój dysk twardy w poszukiwaniu plików jpg i mp3.os.path.isfile nie działa zgodnie z oczekiwaniami

Napisałem następujący skrypt, który działa, jeśli przekazuję go katalogowi z plikiem w katalogu głównym, ale nie zwraca niczego, jeśli przekażę katalog główny.

Jestem nowy w Pythonie, więc bardzo chciałbym pomóc.

def findfiles(dirname,fileFilter): 

    filesBySize = {} 

    def filterfiles(f): 
     ext = os.path.splitext(f)[1][1:] 
     if ext in fileFilter: 
      return True 
     else: 
      False 

    for (path, dirs, fnames) in os.walk(dirname): 
     if len(fileFilter)>0: 
      fnames = filter(filterfiles,fnames) 

     d = os.getcwd() 
     os.chdir(dirname)  
     for f in fnames: 
      if not os.path.isfile(f) : 
       continue 

      size = os.stat(f)[stat.ST_SIZE] 
      if size < 100: 
       continue 
      if filesBySize.has_key(size): 
       a = filesBySize[size] 
      else: 
       a = [] 
       filesBySize[size] = a 
      a.append(os.path.join(dirname, f)) 
      # print 'File Added: %s' %os.path.join(dirname,f) 
      _filecount = _filecount + 1 
     os.chdir(d) 

    return filesBySize 
+1

Czy próbujesz rekursywnie przeszukiwać katalogi? – alexmherrmann

+1

W tej funkcji jest dużo kodu. Co sprawia, że ​​jesteś tak pewny, że jest to wezwanie do 'os.path.isfile (f)', które idzie nie tak? Również twoja funkcja 'filterfiles()' powinna prawdopodobnie 'zwrócić ext w fileFilter', ponieważ masz tam literówkę. – Johnsyweb

+0

Tak, jestem. Domyślam się, że to jest problem, ponieważ gdy go przejrzę, wbudowana funkcja zwraca wartość false, gdy f jest prawdziwym plikiem. Mogłem być daleko. Nie wiesz, gdzie widzisz literówkę? – gmoorevt

Odpowiedz

9

Ah tak.

Dzwonisz pod numer os.path.isfile(f), gdzie f to nazwa pliku w obrębie path. Musisz podać ścieżkę absolutna. Jeśli rzeczywiście to połączenie jest konieczne (zawsze powinno być zwracane True).

Spróbuj zmienić dla pętli do:

qualified_filenames = (os.path.join(path, filename) for filename in fnames) 
    for f in qualified_filenames: 

i powinno być ustawione!

Również połączenia z numerem os.chdir() nie są potrzebne.

I, jak sugeruje się w komentarzach, filterfiles powinien wyglądać mniej więcej tak:

def filterfiles(f): 
    ext = os.path.splitext(f)[1][1:] 
    return ext in fileFilter 

(Przegapiono return).

+1

Dzięki! To załatwiło sprawę. Dzięki za pomoc. – gmoorevt

0

wierzę stałe os.chdir() połączenia są tu komplikuje program (a może nawet zepsuć how os.walk() prace).

Mam skopiowane lepiej wyglądający przykład jak pracować ze ścieżek bez zmian katalogów z the Python documentation:

# Delete everything reachable from the directory named in "top", 
# assuming there are no symbolic links. 
# CAUTION: This is dangerous! For example, if top == '/', it 
# could delete all your disk files. 
import os 
for root, dirs, files in os.walk(top, topdown=False): 
    for name in files: 
     os.remove(os.path.join(root, name)) 
    for name in dirs: 
     os.rmdir(os.path.join(root, name)) 

użyć os.path.join(root, name) kiedy już wybrano name z files.

2

niezwiązanych bezpośrednio do Twojego pytania, ale tutaj są pewne ogólne nowoczesne wskazówek Python ponieważ jesteś nowy w Pythonie:

os.stat(f)[stat.ST_SIZE] 

można zapisać jako

os.stat(f).st_size 

i

if filesBySize.has_key(size): 
    a = filesBySize[size] 
else: 
    a = [] 
    filesBySize[size] = a 

jest lepiej napisane jako:

a = filesBySize.setdefault(size, []) 
+1

lub nawet, ['filesBySize = defaultdict (list); ... filesBySize [rozmiar] .append (f) '] (http://stackoverflow.com/a/8959455/4279) bez' a'. – jfs

3

filesBySize jest raczej nietypowym zgrupowaniem. Można go przenieść poza findfiles() funkcji:

#!/usr/bin/env python 
import os 
import stat 
import sys 
from collections import defaultdict 

def findfiles(rootdir, extensions=None, minsize=100): 
    """Find files with given `extensions` and larger than `minsize`. 

    If `extensions` is None then don't filter on extensions. 
    Yield size, filepath pairs. 
    """ 
    extensions = tuple(extensions) if extensions is not None else extensions 
    for path, dirs, files in os.walk(rootdir): 
     if extensions is not None: # get files with given extensions 
      files = (f for f in files if f.endswith(extensions)) 
     for f in files: 
      f = os.path.join(path, f) 
      try: 
       st = os.stat(f) 
      except os.error: 
       continue # skip 
      if stat.S_ISREG(st.st_mode): # isfile 
       if st.st_size > minsize: 
        yield st.st_size, f 

rootdir = sys.argv[1] # get it from command-line 
files_by_size = defaultdict(list) 
for size, f in findfiles(rootdir, ['.mp3', '.jpg']): 
    files_by_size[size // (1<<20)].append((size, f)) # group in 1M buckets 

import pprint 
pprint.pprint(dict(files_by_size)) # pretty print 

Nie ma potrzeby korzystania os.chdir(), wystarczy zadzwonić os.path.join(path, f).

Powiązane problemy