Aller au contenu

comment trouver un fichier depuis un lisp


thierryd

Messages recommandés

Les fonctions s'appellent FINDFILE et OPEN et CLOSE avec Prin1, par exemple. Mais, comme indiqué dans un message très récent, je conseille l'usage des fonctions Doslib, qu'on trouve sur le site de Mcneel.

 

[Edité le 11/1/2006 par Tramber]

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Lien vers le commentaire
Partager sur d’autres sites

salut,

 

en fait j'ai bien installé doslib et je trouve toutes ces fonctions trés bien pensées (un grand merci au site de Mcneels http://www.mcneel.com/download.htm. je vous le conseille)

 

il y a bien cette fonction : (dos_openp filename) mais l'utilisateur doit donner le chemin complet.

 

l'idée serait plus de passer par l'explorateur et de revenir sur le lisp une fois le fichier trouvé.

 

cordialement

 

 

Lien vers le commentaire
Partager sur d’autres sites

DosLIB c'est bien...mais personellement j'essai d'éviter quand c'est possible....

charger un ARX à chaque fois qu'une commande est lancé....glup !!

 

je ne suis pas trop ouvert à ça....

ceci implique qu'il faut charger le arx via ce même lisp ou encore manuellement AVANT d'exécuter la fonction.

 

De plus, si ce même arx change de répertoire ou s'efface ou encore....

 

le programme ne fonctionne plus...voilà....il est maintenant dépendant de DosLIB.

 

Je n'ai rien contre DosLIB...je l'ai même utiliser à plusieurs reprise dans le temps...

mais il faut faire attention et programmer de fait qu'il y a ce fichier.

 

Vlisp pourrait très bien faire le boulo avec un While..et

(vl-directory-files.......

Sky is the limit.....Mon oeuil !!

Lien vers le commentaire
Partager sur d’autres sites

pour CADarome

 

tu n'es pas obligé de charger l'arx à chaque fois, tu peux demander à ce qu'il soit chargé à chaque démarrage d'Autocad

 

outil, charger une application, en bas à droite de la case de dialogue, sous la petite valise: contenu

 

cordialement

 

mais j'aimerais avoir l'avis d'une majorité d'utilisateurs

 

en ce qui me concerne le seul problème réside dans le fait qu'un lisp créé avec quelques fonctions DosLIB ne peut pas être donné à quelqu'un sans lui préciser qu'il doit charger l'arx en question

Lien vers le commentaire
Partager sur d’autres sites

Mon avis personnel:

 

Je pense que si l'on veut distribuer une routine, il vaut mieux la prévoir indépendante de toutes applications non disponible en standard.

Je trouve pas très correct d'imposer une application tierce aux autres utilisateurs qu'ils n'ont pas forcément envie de l'installer ou de l'utiliser.

 

Bien que ces fonctions supplémentaires soyent très bien et facilitent certaines taches de programmation, on devrait se les réserver pour son usage personnel.

 

Et puis si un jour, si la diffussion de cette extension est arrêtée ou devenue payante:

Qu'est ce qu'on fait? On révise tout nos codes! :casstet:

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

J'ai bien cette routine qui pourrait convenir, mais le souci, c'est que le programme continue alors que l'écriture du fichier continue et du coup, ça plante. A moins de mettre une boucle d'attente, si quelqu'un à une solution, je suis preneur

 

@+

 

(defun c:rech(/ resultat)

 (defun recherche_lisp(lecteur fichier / f n rep result)
   (command "shell" (strcat "dir " lecteur "\\*.lsp /on /s /b > dir.tmp"))
   (setq n 0)
   (while (< n 1000000)
     (setq n (1+ n))
   )
   (setq f (open "dir.tmp" "r"))
   (while (setq rep (read-line f))
     (if (eq (strcase (vl-filename-base rep)) (strcase fichier))
       (setq result (list (vl-filename-directory rep) (vl-filename-base rep)))
     )
   )
   (close f)
   (vl-file-delete "dir.tmp")
   result
 )

 (if (setq resultat (recherche_lisp "c:" "mon_lisp"))
   (alert (strcat "Le fichier " (strcase (cadr resultat)) " est dans le répertoire\n \n" (strcase (car resultat))))
 )
 (princ)
)

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

pour CADarome

 

tu n'es pas obligé de charger l'arx à chaque fois, tu peux demander à ce qu'il soit chargé à chaque démarrage d'Autocad

 

outil, charger une application, en bas à droite de la case de dialogue, sous la petite valise: contenu

 

cordialement

 

mais j'aimerais avoir l'avis d'une majorité d'utilisateurs

 

en ce qui me concerne le seul problème réside dans le fait qu'un lisp créé avec quelques fonctions DosLIB ne peut pas être donné à quelqu'un sans lui préciser qu'il doit charger l'arx en question

 

Pour thierryd...

 

oui,...en fait, le programme ne fonctionnera pas si le ARX est manquant..

donc...c'est au programmeur de prévoir si le fichier est chargeé ou pas..

et c'est au programmeur d'associer le chemin d'accès à ce fichier ARX.

 

ex:

 

 (if (not (member "DosLIB.arx" (arx)))
(arxload "DosLIB.arx"
 (alert "Désolé, le fichier DosLIB.arx est manquant.
Le programe va maintenant fermer par ce que le programmeur n'a pas su
prévoir cette hypothèse.")))

 

You see ?

Aussi, serais-t-il bon de prévoir les version des fichier ARX...

car ces fichiers ne sont pas tous compatible au versions d'autoCAD.

 

Oops !!... :exclam:

 

 (setq cadver (getvar "acadver"))

 

 

 

[Edité le 19/1/2006 par CADarome]

Sky is the limit.....Mon oeuil !!

Lien vers le commentaire
Partager sur d’autres sites

J'ai bien cette routine qui pourrait convenir, mais le souci, c'est que le programme continue alors que l'écriture du fichier continue et du coup, ça plante. A moins de mettre une boucle d'attente, si quelqu'un à une solution, je suis preneur

 

@+

 

(defun c:rech(/ resultat)

 (defun recherche_lisp(lecteur fichier / f n rep result)
   (command "shell" (strcat "dir " lecteur "\\*.lsp /on /s /b > dir.tmp"))
   (setq n 0)
   (while (< n 1000000)
     (setq n (1+ n))
   )
   (setq f (open "dir.tmp" "r"))
   (while (setq rep (read-line f))
     (if (eq (strcase (vl-filename-base rep)) (strcase fichier))
       (setq result (list (vl-filename-directory rep) (vl-filename-base rep)))
     )
   )
   (close f)
   (vl-file-delete "dir.tmp")
   result
 )

 (if (setq resultat (recherche_lisp "c:" "mon_lisp"))
   (alert (strcat "Le fichier " (strcase (cadr resultat)) " est dans le répertoire\n \n" (strcase (car resultat))))
 )
 (princ)
)

 

Patrick...

Il serait plus sage d'éviter la loupe...

 
;|	Recherche de fichier									.
Note: 	le fichier peut être n'importe quelle extension					.
	le lecteur doit exister et être suivit de 2opoints comme ceci   -->  c:		.
											|;

(defun c:recherche_fichier (/ fichier lecteur)
 (setq fichier  (strcase (getstring "Nom de votre fichier: "))
 lecteur (getstring "Choisissez votre lecteur: ")
 )
(command "shell" (strcat "dir " lecteur "\\" fichier "/on /s /b > " lecteur "\\dir.txt"))
(startapp "notepad.exe" (strcat lecteur "\\dir.txt"))
)

Sky is the limit.....Mon oeuil !!

Lien vers le commentaire
Partager sur d’autres sites

Il serait plus sage d'éviter la loupe...

???

 

Avec ton prog, tu as le même souci que sur le mien. Quand tu lance la commande shell, tu lances tout de suite le notepad qui ne trouve pas le fichier dir.txt

L'avantage de passer par un fichier et de prendre tous les lsp, c'est de pouvoir faire une recherche multiple (avec une légère modif du lisp)

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Il serait plus sage d'éviter la loupe...

???

 

Avec ton prog, tu as le même souci que sur le mien. Quand tu lance la commande shell, tu lances tout de suite le notepad qui ne trouve pas le fichier dir.txt

L'avantage de passer par un fichier et de prendre tous les lsp, c'est de pouvoir faire une recherche multiple (avec une légère modif du lisp)

 

@+

 

??? le soucis de quoi ??

j'ai pas de soucis moi....le prog fonctionne très bien.

et non seulement il fait exactement ce que tu veux.....

mais en plus il te donne la possiblité de :

 

1) voir si il y plus qu' un seul fichier qui porte le même nom.

2) te permet de filtrer le type de fichier

3) te permet de localiser sur quel lecteur et/ou répertoire pour éviter qu'il "SCAN" ton disque dur au complet juste pour peut-être trouver un fichier.

4) et finalement garder le fichier txt pour référence

ce qui est pratique lorsque tu veux imprimer une liste de tes fichiers.

 

toi, tu as fait 2 boucles....(chose que j'essai d'éviter toujour en programmation dans la mesure du possible). pour finalement faire quoi au juste ? ...ah oui...

ajouter le nom de ton fichier à la fin du répertoire pour créer le chemin complet

...chose que tu avais enlever au début. avec.."../b > dir...."

 

En plus, tu créer un fichier .TMP !!? c'est quoi ça ?..Windows doit faire une recherche dans sa clé de registre pour finalement s'appercevoir qu'un fichier TMP n'est associé à rien.

Windows prend alors "notepad" par défault pour éditer le fichier en mode écriture.

 

Voilà.....pour le reste je trouve bien pensé le fait d'utiliser une commande DOS.

 

 

Sky is the limit.....Mon oeuil !!

Lien vers le commentaire
Partager sur d’autres sites

Ah oui, c'est exact, je n'ai pas pensé aux doublons

Quant à mes deux boucles

La première est pour attendre que ma commande dos se termine afin d'examiner plus tard le fichier créé

La deuxième est pour lire le fichier et de plus, j'indique le nom du répertoire et le nom du fichier séparément

Le tmp est pour indiquer que c'est du temporaire et je l'efface à la fin

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Patrick35

 

A la place de:

 

(setq n 0)

(while (< n 1000000)

(setq n (1+ n))

)

 

j'utilise

 

(prompt "\nAppuyer sur une touche pour continuer!")

(grread)

 

C'était pratiques dans les environnements W98/ME car je voyais les fenêtre DOS s'afficher et se fermer selon un délai de traitement propre a chacune. Donc j'attendais que les fenêtres soyent toutes fermées pour continuer.

Sous XP ces fenêtres ne sont pas forcément au premier plan comme avant (on ne remarque rien) donc moins interressant.

 

Je pense que t'as prévu large dans ta boucle d'attente, mais si le traitement est plus long, ben .... ton résultats sera faussé.

 

Ma solution est manuelle et pas évidente pour une personne non avertie.

 

Autrement en regardant la fonction (vl-directory-files je me demandes si une solution pure en lisp n'est pas possible...? l'option -1 est interressante.

 

A creuser avec une fonction itérative imbriquée.

 

 

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Salut Bonus

C'est une solution

J'etais en train de penser à autre chose

C'est de regarder si la taille du fichier concerné n'augmente pas et pour éviter que ça aille trop vite, mettre une boucle d'attente du type

(setq taille -1)
(while (/= (vl-file-size "dir.tmp") taille)
 (setq taille (vl-file-size "dir.tmp") n 0)
 (while (< n 1000)
   (setq n (1+ n))
 )
)

Mais apparemment, ça ne marche pas :(

 

Avec vl-directory-files, c'est possible et ça éviterait la commande dos, il reste à trouver le bon algorithme pour recréer l'arborescence

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Avec vl-directory-files, c'est possible et ça éviterait la commande dos, il reste à trouver le bon algorithme pour recréer l'arborescence

 

Salut Patrick_35

 

Je me suis un peu amusé a chercher une solution. :casstet:

Je t'avoue qu'a un moment mes neurones se mélangaient dans les imbriquation de while mapcar foreach avec fonction récursive.:P

 

Mais au final, voilà l'algorithme!

 

Sur ma machine il a mis 2mm pour me lister tous les dossiers de C:\ :mad:

Bien sûr si tu vises au départ un sous-dossier de plus en plus éloigné dans l'aborescence, les résultats seront de plus en plus rapides. :cool:

 

Il est facile d'ajouter une ou 2 lignes d'entrées utilsateur pour définir la variable disk_unit et la variable folder_name. ;)

 

(defun extract_folder (lst_fold / l_dir l)
(setq l_dir '()) 
(foreach n lst_fold
	(setq l (vl-directory-files n nil -1))
	(if (eq (car l) ".")
		(setq l (cddr l))
	)
	(cond
		(l
			(setq l_dir
				(append
					(mapcar
						'(lambda (x)
							(strcat n  x "/")
						)
						l
					)
					l_dir
				)
			)
		)
	)
)
l_dir
)
(defun c:list_directory ( / disk_unit folder_name folder_list lst_str)
(setq
	disk_unit "C:"
	folder_name (strcat disk_unit "/")
	folder_list (list folder_name)
	lst_str folder_list
)
(while (setq lst_str (extract_folder lst_str))
	(setq folder_list
		(append
			folder_list
			lst_str
		)
	)
)
(textscr)
(mapcar 'print folder_list)
(prin1)
)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Il n’y a pas à dire, Bonus est un bon, même un très bon. :cool: Je n'ai même pas eu le temps de rechercher la solution ;)

Je me suis permis, si tu le permets de modifier un peu ton lisp pour compléter la recherche

 

@+

 

(defun extract_folder (lst_fold / l_dir l)
 (setq l_dir '()) 
 (foreach n lst_fold
   (setq l (vl-directory-files n nil -1))
   (if (eq (car l) ".")
     (setq l (cddr l))
   )
   (cond
     (l
       (setq l_dir
         (append
           (mapcar
             '(lambda (x)
                (strcat n x "/")
              )
              l
           )
           l_dir
         )
       )
     )
   )
 )
 l_dir
)

(defun message(rep fichier)
 (if (vl-directory-files rep fichier 1)
   (princ (strcase (strcat "\nFichier " fichier(s) " trouvé(s) dans le répertoire " (vl-string-translate "/" "\\" rep))))
 )
)

(defun list_directory (disk_unit fichier / disk_unit folder_name folder_list lst_str)
 (setq
;    disk_unit "C:"
   folder_name (strcat disk_unit "/")
   folder_list (list folder_name)
   lst_str folder_list
 )
 (message folder_name fichier)
 (while (setq lst_str (extract_folder lst_str))
   (setq folder_list
     (append
       folder_list
       lst_str
     ) 
   )
   (foreach rep lst_str
     (message rep fichier)
   )
 )
;  (textscr)
;  (mapcar 'print folder_list)
 (prin1)
)

(if (setq lec (getstring "Lecteur : "))
 (if (setq fic (getstring T "Fichier recherché : "))
   (list_directory lec fic)
 )
)

; exemple (list_directory "c:" "acadinfo.lsp")

 

[Edité le 24/1/2006 par Patrick_35]

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Salut Patrick_35

 

J'ai fais le même exercice que toi!

 

C'est similaire a ce que tu as fais, mais je crois qu'une coquiile c'est glissé.

Tu fais:

(foreach rep lst_str

 

folder_list à la place lst_str serait plus sûr

 

et puis j'aurais vu un argument en plus pour la fonction.

; exemple (list_directory "c:" "/program files/" "*.lin")

pour limiter (quand c'est possible) le temps de recherche.

 

L'emploi de caractère génériques à l'air de fonctionner. ;)

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Salut Bonus

Non, c'est volontaire de rechercher sur lst_str plutôt que sur folder_list car ça permet en cas de caractère générique ou de doublon de faire afficher les résultats au fur et à mesure et ça évite de patienter comme un idiot en attendant que ça se passe

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Oups Excuse :exclam:

 

J'avais pas vu que tu avais intégré ta ligne d'affichage dans la boucle.

 

En effet comme ça on voit qui se passe quelque chose au fur et à mesure ;)

 

Mon (mapcar 'print folder_list) est mal conçu je parcours 2 fois la liste, dans la boucle c'est mieux!

D'ailleurs on peut peut être supprimer cette liste qui ne sert plus à rien a part "bouffer" de la mémoire pour rien.

A moins que l'on veuille récupérer cette liste pour une autre utilisation....

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Quand même, Y-a un truc qui ne vas pas.

 

Ton idée est bonne, mais je crois que tout les fichiers à la racine seront ignoré.

Tu devrais faire la même ligne à "blanc" avant la boucle pour traiter la racine.

 

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité