45 votes

Comment créer un nom de fichier s'incrémentant

Je crée un programme qui va créer un fichier et le sauvegarder dans le répertoire avec le nom de fichier sample.xml. Une fois le fichier enregistré, lorsque j'essaie d'exécuter le programme à nouveau, il écrase l'ancien fichier par le nouveau parce qu'ils ont le même nom de fichier. Comment puis-je incrémenter les noms de fichiers pour que chaque fois que je tente d'exécuter le code à nouveau, il va incrémenter le nom de fichier et ne pas écraser l'ancien. Je pense à vérifier d'abord le nom de fichier dans le répertoire et si ils sont identiques, le code générera un nouveau nom de fichier :

fh = open("sample.xml", "w")
rs = [blockresult]
fh.writelines(rs)
fh.close()

3voto

Malo Pocheau Points 71

Une autre solution qui évite l'utilisation d'une boucle while est d'utiliser la fonction os.listdir() qui retourne une liste de tous les fichiers et répertoires contenus dans un répertoire dont le chemin est pris en argument.

Pour répondre à l'exemple de la question, en supposant que le répertoire dans lequel vous travaillez contient uniquement des fichiers "sample_i.xlm" indexés à partir de 0, vous pouvez obtenir facilement le prochain index pour le nouveau fichier avec le code suivant.

import os

nouvel_index = len(os.listdir('chemin_vers_le_répertoire_contenant_uniquement_des_fichiers_sample_i'))
nouveau_fichier = open('chemin_vers_le_répertoire_contenant_uniquement_des_fichiers_sample_i/sample_%s.xml' % nouvel_index, 'w')

3voto

Matrix Programmer Points 471

Vous pouvez utiliser une boucle tant qu'avec un compteur qui vérifie si un fichier avec un nom et la valeur du compteur existe. Si c'est le cas, passez à l'étape suivante sinon arrêtez et créez un fichier.

Je l'ai fait de cette manière pour l'un de mes projets :

from os import path
import os

i = 0
flnm = "Répertoire\\NomFichier" + str(i) + ".txt"
while path.exists(flnm) :
    flnm = "Répertoire\\NomFichier" + str(i) + ".txt"
    i += 1
f = open(flnm, "w") #faites ce que vous voulez avec ce fichier...
f.write(str(var))
f.close() # assurez-vous de le fermer.

Voici le compteur i qui commence à 0 et une boucle tant qu'il vérifie à chaque fois si le fichier existe, s'il existe, il continue sinon il sort de la boucle et crée un fichier que vous pouvez personnaliser. Assurez-vous également de le fermer sinon le fichier restera ouvert, ce qui peut causer des problèmes lors de sa suppression. J'ai utilisé path.exists() pour vérifier si un fichier existe. Ne faites pas from os import *, cela peut causer des problèmes lorsque nous utilisons la méthode open(), car il y a une autre méthode os.open() qui peut provoquer une erreur. TypeError: Integer attendu. (obtenu str) Sinon, je vous souhaite une bonne année à tous.

2voto

Vorticity Points 1024

Sans stocker les données d'état dans un fichier supplémentaire, une solution plus rapide aux solutions présentées ici serait de faire ce qui suit :

from glob import glob
import os

files = glob("somedir/sample*.xml")
files = files.sorted()
cur_num = int(os.path.basename(files[-1])[6:-4])
cur_num += 1
fh = open("somedir/sample%s.xml" % cur_num, 'w')
rs = [blockresult]
fh.writelines(rs)
fh.close()

Cela continuera également à s'incrémenter, même si certains fichiers de numéro inférieur disparaissent.

L'autre solution que j'aime ici (soulignée par Eiyrioü) est l'idée de conserver un fichier temporaire contenant votre numéro le plus récent :

temp_fh = open('somedir/curr_num.txt', 'r')
curr_num = int(temp_fh.readline().strip())
curr_num += 1
fh = open("somedir/sample%s.xml" % cur_num, 'w')
rs = [blockresult]
fh.writelines(rs)
fh.close()

1voto

chumbaloo Points 543

Un autre exemple utilisant la récursivité

import os
def checkFilePath(testString, extension, currentCount):
    if os.path.exists(testString + str(currentCount) +extension):
        return checkFilePath(testString, extension, currentCount+1)
    else:
        return testString + str(currentCount) +extension

Utilisation :

checkFilePath("myfile", ".txt" , 0)

1voto

Woods26 Points 11

J'avais besoin de faire quelque chose de similaire, mais pour les répertoires de sortie dans un pipeline de traitement de données. J'ai été inspiré par la réponse de Vorticity, mais j'ai ajouté l'utilisation de regex pour obtenir le nombre final. Cette méthode continue d'incrémenter le dernier répertoire, même si des répertoires de sortie numérotés intermédiaires sont supprimés. Il ajoute également des zéros de tête afin que les noms se trient alphabetiquement (c'est-à-dire largeur 3 donne 001, etc.)

def get_unique_dir(path, width=3):
    # s'il n'existe pas, le créer
    if not os.path.isdir(path):
        log.debug("Création d'un nouveau répertoire - {}".format(path))
        os.makedirs(path)
        return path

    # s'il est vide, utilisez
    if not os.listdir(path):
        log.debug("Utilisation du répertoire vide - {}".format(path))
        return path

    # sinon, incrémentez le dossier de nombre le plus élevé de la série

    def get_trailing_number(search_text):
        serch_obj = re.search(r"([0-9]+)$", search_text)
        if not serch_obj:
            return 0
        else:
            return int(serch_obj.group(1))

    dirs = glob(path + "*")
    num_list = sorted([get_trailing_number(d) for d in dirs])
    highest_num = num_list[-1]
    next_num = highest_num + 1
    new_path = "{0}_{1:0>{2}}".format(path, next_num, width)

    log.debug("Création d'un nouveau répertoire incrémenté - {}".format(new_path))
    os.makedirs(new_path)
    return new_path

get_unique_dir("output")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X