Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

liste fichiers mais sans repertoires

15 réponses
Avatar
pika
Bonjour
Quand j'utilise os.path.walk, la liste de repertoires
qu'il me donne est ok mais la liste de fichiers contient
aussi les repertoires, comment faire pour avoir rien que des fichiers
à part tester ceux ci un par un ?

10 réponses

1 2
Avatar
cho7
"pika" a écrit dans le message de news:
43985065$0$27892$
Bonjour
Quand j'utilise os.path.walk, la liste de repertoires
qu'il me donne est ok mais la liste de fichiers contient
aussi les repertoires, comment faire pour avoir rien que des fichiers
à part tester ceux ci un par un ?


J'suis pas sûr d'avoir saisi ton problème.
walk attent en 2eme paramètre une fonction callback ayant 3 attributs, du
genre :

def traiter(racine,dossier,fichiers):
for fichier in fichiers:
print os.path.join(dossier,fichier)
#ou bien pour n'afficher que le nom du fichier sans le chemin
print fichier

os.path.walk(chemin,traiter,None)

Que veux tu faire exactement ??


Donc tu va

Avatar
pika
cho7 wrote:
"pika" a écrit dans le message de news:
43985065$0$27892$

Bonjour
Quand j'utilise os.path.walk, la liste de repertoires
qu'il me donne est ok mais la liste de fichiers contient
aussi les repertoires, comment faire pour avoir rien que des fichiers
à part tester ceux ci un par un ?



J'suis pas sûr d'avoir saisi ton problème.
walk attent en 2eme paramètre une fonction callback ayant 3 attributs, du
genre :

def traiter(racine,dossier,fichiers):
for fichier in fichiers:
print os.path.join(dossier,fichier)
#ou bien pour n'afficher que le nom du fichier sans le chemin
print fichier

os.path.walk(chemin,traiter,None)


le probleme c'est quand tu fais print fichier, il affiche
les fichiers mais aussi les repertoires, je pourrais faire
os.isfile(path) sur chacun, mais j'aimerais savoir si ya pas
une autre methode pour enlever les repertoires de la liste


Avatar
cho7
Quel est ton système d'exploitation ?

Chez moi (Linux), je n'ai bien QUE les fichiers.
Au boulot (Windows 2000), idem.

Alors je dis que je ne vois pas d'où vient ton problème... :(
Avatar
Do Re Mi chel La Si Do
Bonsoir !

Chez moi, sous windows XP, j'ai AUSSI les répertoires, dans la liste des
fichiers.

@-salutations

Michel Claveau
Avatar
Pierre Quentel
Bonjour
Quand j'utilise os.path.walk, la liste de repertoires
qu'il me donne est ok mais la liste de fichiers contient
aussi les repertoires, comment faire pour avoir rien que des fichiers
à part tester ceux ci un par un ?


Il vaut mieux utiliser os.walk (introduit dans la version 2.3) que
os.path.walk :

for root,dirs,files in os.walk(chemin):
for filename in files:
print filename

Pierre

Avatar
Do Re Mi chel La Si Do
Bonsoir !

Oui, c'est mieux (si on veut juste la liste des fichiers).
Et, en plus, les directories n'y sont pas.

@-salutations

Michel Claveau
Avatar
Florent Manens
Bonjour,

Le 08-12-2005, Pierre Quentel a écrit :
Bonjour
Quand j'utilise os.path.walk, la liste de repertoires
qu'il me donne est ok mais la liste de fichiers contient
aussi les repertoires, comment faire pour avoir rien que des fichiers
à part tester ceux ci un par un ?


Il vaut mieux utiliser os.walk (introduit dans la version 2.3) que
os.path.walk :

for root,dirs,files in os.walk(chemin):
for filename in files:
print filename


Pour mes besoins (sous windows uniquement, os.walk n'est pas assez
rapide. J'ai de bien meilleurs performances (en particulier lors d'un
2ème passage) en utilisant l'API win32 (pywin32 est requis). C'est une
copie modifiée de os.walk :


def winwalk( top, topdown=True, onerror=None ):
from win32file import FindFilesW, FindFilesIterator
from os.path import join, islink
# We may not have read permission for top, in which case we can't
# get a list of the files the directory contains. os.path.walk
# always suppressed the exception then, rather than blow up for a
# minor reason when (say) a thousand readable directories are still
# left to visit. That logic is copied here.

try:
dirs, nondirs = [], []
for name in FindFilesIterator( join( top, "*" ) ):
if name[8] not in [".", ".."]:
# File Attributes. A combination of the win32file.FILE_ATTRIBUTE_*
# flags.
if name[0] & win32file.FILE_ATTRIBUTE_DIRECTORY:
dirs.append( name[8] )
else:
nondirs.append( name[8] )

except Exception, err:
if onerror is not None:
onerror( err )
return
if topdown:
yield top, dirs, nondirs
for name in dirs:
path = join( top, name )
if not islink( path ):
for content in winwalk( path, topdown, onerror ):
yield content
if not topdown:
yield top, dirs, nondirs

Si vous comparez avec os.walk, vous pouvez voir que j'ai changé la
position du try...except, je ne sais pas si le comportement est
*exactement* le même.

Normalement, ceci :
for root,dirs,files in winwalk(chemin):
for filename in files:
print filename

devrait fonctionner.

--
Florent Manens



Avatar
Do Re Mi chel La Si Do
Salut !

Si tu es sous windows, et si tu cherches la rapidité, le mieux, c'est,
hélas, de wrapper DIR.

J'avais mis un message là-dessus, il y a quelques mois.

Exemple :
import os
a = os.popen4("dir C:VivePythonsouswin*.py /B /S")
listefichiers = [f[:-1] for f in a[1].readlines()]

On a alors toutes les possibilités du DIR (fichiers cachés, sélection par
attributs, limites de dates, etc.)


@-salutations

Michel Claveau
Avatar
Florent Manens
Le 09-12-2005, Do Re Mi chel La Si Do a écrit :
Salut !

Si tu es sous windows, et si tu cherches la rapidité, le mieux, c'est,
hélas, de wrapper DIR.

J'avais mis un message là-dessus, il y a quelques mois.

Exemple :
import os
a = os.popen4("dir C:VivePythonsouswin*.py /B /S")
listefichiers = [f[:-1] for f in a[1].readlines()]

On a alors toutes les possibilités du DIR (fichiers cachés, sélection par
attributs, limites de dates, etc.)


J'ai déjà lu ton astuce plusieurs fois mais elle ne suffit pas pour mon
besoin. En particulier, les accents sont mal gérés par dir.

De plus, elle n'est pas plus rapide que ma solution.

J'ai fait quelques tests (sur un disque de 10 Go, 170000 fichiers) dont
voici les résultats : (Windows XP Home, je n'ai pas les mêmes résultats
sur un windows 2000)

Passe 1 :
Temps test_dir() : 108.356004185
Temps test_walk() : 19.7642214304
Temps test_winwalk() : 3.74159872274 <-- ça doit être les effets du
cache généré par "dir"

Passe 2 :
Temps test_dir() : 4.95025540956
Temps test_walk() : 19.5955726217
Temps test_winwalk() : 3.47585098106

Lors de l'utilisation de l'API win32, un cache est créé et une
indexation des fichiers est faite par windows, ça explique la forte
baisse du temps de scan (alors que os.walk est en temps constant). dir
et winwalk doivent utiliser sensiblement les mêmes API (et puis je
trouve ça plus propre que wrapper dir :p).

Le programme de test (Pour ceux qui suivent, j'ai corrigé un problème
d'import qui était présent dans la version précédente de "winwalk") :

Remarque : Le nombre de fichiers trouvé n'est pas le même pour les 3
techniques (c'est proche mais pas identique).

import os

def winwalk( top, topdown=True, onerror=None ):
from win32file import FindFilesW, FindFilesIterator, FILE_ATTRIBUTE_DIRECTORY
from os.path import join, islink
# We may not have read permission for top, in which case we can't
# get a list of the files the directory contains. os.path.walk
# always suppressed the exception then, rather than blow up for a
# minor reason when (say) a thousand readable directories are still
# left to visit. That logic is copied here.

try:
dirs, nondirs = [], []
for name in FindFilesIterator( join( top, "*" ) ):
if name[8] not in [".", ".."]:
# File Attributes. A combination of the win32file.FILE_ATTRIBUTE_*
# flags.
if name[0] & FILE_ATTRIBUTE_DIRECTORY:
dirs.append( name[8] )
else:
nondirs.append( name[8] )

except Exception, err:
if onerror is not None:
onerror( err )
return
if topdown:
yield top, dirs, nondirs
for name in dirs:
path = join( top, name )
if not islink( path ):
for content in winwalk( path, topdown, onerror ):
yield content
if not topdown:
yield top, dirs, nondirs

def test_dir():
a = os.popen4("dir C:*.* /B /S")
listefichiers = [f[:-1] for f in a[1].readlines()]
print "Nombre de fichiers %s" % len(listefichiers)

def test_walk():
listefichiers = []
for root,dirs,files in os.walk("c:"):
listefichiers.extend(files)
print "Nombre de fichiers %s" % len(listefichiers)

def test_winwalk():
listefichiers = []
for root,dirs,files in winwalk("c:"):
listefichiers.extend(files)
print "Nombre de fichiers %s" % len(listefichiers)

if __name__ == "__main__":
from timeit import Timer
t1 = Timer("test_dir()", "from __main__ import test_dir")
t2 = Timer("test_walk()", "from __main__ import test_walk")
t3 = Timer("test_winwalk()", "from __main__ import test_winwalk, winwalk")
print " Temps test_dir() : %s" % t1.timeit(number=1)
print " Temps test_walk() : %s" % t2.timeit(number=1)
print " Temps test_winwalk() : %s" % t3.timeit(number=1)

--
Florent Manens


Avatar
Do Re Mi chel La Si Do
Bonjour !


Quelques petites précisions :

Concernant les disques durs, il y a de multiples niveaux de caches. Celui de
Windows en est un. Mais on oublie souvent celui du contrôleur du disque dur
(souvent 2, 4 ou 8 Mo).

Et, quand on parle du cache de windows, il faudrait distinguer : le cache
d'accès aux fichiers, le cache de lancement des programmes (cache externe,
avec prefetch), le cache de DLL (interne, et externe avec DLLcache),

Jouent également : le type de système de fichiers/formatage (NTFS est plus
lent, gestion des derniers accès ou non) ; les antivirus (certains ne
rescanne pas un fichier accédé qq secondes auparavant, d'autres oui) et de
leur configuration ; de certains paramètres de windows (indexation lancée /
pas lancée / désactivée, pour le service et pour le disque).

Il y a encore d'autres éléments.

Il résulte de tout ça que, pour tester la vitesse d'une façon de faire, il
faut faire tourner deux fois, de suite, chaque méthode ; pour diminuer
l'impact des caches. Mais, surtout, IL FAUT ETEINDRE ET REDEMARRER
L'ORDINATEUR ENTRE CHAQUE CHANGEMENT DE METHODE. Un reboot simple ne suffit
pas toujours.


Un autre critère, jouant sur la vitesse, peut être trouvé dans les critères
de sélection des fichiers. Par exemple, si je veux tous les fichiers images
(Jpeg) commençant par ARD, j'utilise : DIR ard*.jpg /S /B alors que les
différents walk nécessitent plus de code, avec un temps d'exécution rallongé
d'autant.



Autre chose : le fait de ne pas obtenir la même chose, entre différentes
méthodes laisse penser à un manque de cohérence, entre les modes de
recherche. En clair, certains paramètres sont mal positionnés. Par exemple,
sur un disque, j'ai plus d'un million de fichiers. Et j'obtiens exactement
la même chose, avec les trois méthodes, sauf si j'examine les répertoires
systèmes, dont le contenu de certains change en continu (surtout à cause des
fichiers temporaires).



Quand aux accents, je suppose qu'il s'agit d'un mauvais choix du code-page
(850 par défaut pour XP), et/ou de police. Car, sur mes configs, non
seulement DIR gère correctement les accents, mais il traite sans problème
des fichiers avec des noms Unicode (plus précisément en cyrillique).
(Éventuellement CMD /U permet de forcer le travail en unicode).




@-salutations

Michel Claveau
1 2