[R] Dernière ligne d'un fichier : Vide ou pas ?

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Jerem
Niveau 2
Niveau 2
Messages : 25
Enregistré le : ven. 17 mai 2013 11:13
Status : Hors ligne

[R] Dernière ligne d'un fichier : Vide ou pas ?

#1

Message par Jerem »

Bonjour à tous,

Je me retrouve devant un problème plus compliquer à résoudre que je ne l'avais imaginé.

J'ai besoin de savoir si un fichier se termine par un saut de ligne ou non.
En théorie c'est assez simple, il suffit de vérifier si la dernière ligne est vide ou non. En pratique, s'il n'y a qu'un seul saut de ligne à la fin du fichier je trouve toujours que la dernière ligne n'est pas vide, alors qu'elle l'est.

Par exemple, je trouve le même résultat que mon fichier contienne ceci :

"Ligne 1
Ligne 2
Ligne 3"


Ou ceci :

"Ligne 1
Ligne 2
Ligne 3
"


La différence est subtile, mais quand on fait un writeline en fin de fichier la différence est notable. Dans un cas tout est sur la même ligne dans l'autre sur 2 lignes différentes et ça change tout.

Dans les deux exemples ci-dessus un FileReadLine ("monfichier.txt", -1) retourne "Ligne 3". Et ce n'est pas cool.
Avec un saut de ligne supplémentaire cela n'est plus vrai.
Ma version d'AutoIT est 3.3.15.0 (Beta).

J'ai essayer d'autres méthodes sans succès. Quelqu'un aurait une idée ?
Modifié en dernier par Jerem le mer. 03 janv. 2018 15:06, modifié 1 fois.
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2272
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: Dernière ligne d'un fichier : Vide ou pas ?

#2

Message par jchd »

Avec un FileRead et ça :

Code : Tout sélectionner

Local $s = "a" & @CRLF & "b" & @CRLF & "c" & @CRLF & "d"

ConsoleWrite(_FinalEmpty($s) & @LF)
$s &= @CRLF
ConsoleWrite(_FinalEmpty($s) & @LF)

Func _FinalEmpty($st)
	Return StringRegExp($st, "\R$")
EndFunc
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
sylvanie
Niveau 11
Niveau 11
Messages : 1550
Enregistré le : jeu. 26 juil. 2007 21:31
Localisation : Paris
Status : Hors ligne

Re: Dernière ligne d'un fichier : Vide ou pas ?

#3

Message par sylvanie »

Bonjour, si on ne souhaite pas mémoriser l'ensemble du contenu du fichier, on peut l'ouvrir en mode binaire et se positionner sur le dernier caractère.
Puis on lit le dernier octet, si il y a un retours chariot DOS ou Unix, ce caractère vaut 0x0a :

Code : Tout sélectionner

#include <Constants.au3>

$Document=@DesktopDir&"\tst_CRLF.txt"
$hnd=FileOpen($Document,16)
If $hnd=-1 Then exit 1
FileSetPos($hnd,-1,$FILE_END)
$ENDCHAR=FileRead($hnd,1)
$MESSAGE="Return not detected"
If $ENDCHAR="0x0a" Then $MESSAGE="Return detected"
ConsoleWrite($MESSAGE&@CRLF)
Exit 0

Toi qui cherche à mettre le doigt sur la solution, appuie sur F1.
Jerem
Niveau 2
Niveau 2
Messages : 25
Enregistré le : ven. 17 mai 2013 11:13
Status : Hors ligne

Re: Dernière ligne d'un fichier : Vide ou pas ?

#4

Message par Jerem »

Peut-être que je me trompe, mais je suppose qu'un fileread est plus gourmand en temps et en ressource qu'un filereadline.
Ça semblerait logique, sauf si le file readline parcourt tout le fichier pour arriver à la dernière ligne et la lire.

Mais si je me trompe alors la première proposition est bonne. J'étais tellement obnubilé par cette dernière ligne que j'en ai oublié que le fichier complet contient forcément tous les caractères du fichier.

La proposition du mode binaire est aussi très intéressante et se rapproche beaucoup de mon idée de base, sauf que cela devrait fonctionner.
Je vais tester cela.

Merci à vous 2.
Jerem
Niveau 2
Niveau 2
Messages : 25
Enregistré le : ven. 17 mai 2013 11:13
Status : Hors ligne

Re: Dernière ligne d'un fichier : Vide ou pas ?

#5

Message par Jerem »

Le mode binaire n'est pas nécessaire, ce qui m'arrange car le fichier est déjà ouvert en lecture avant que je fasse mon test pour les besoin de mon programme.

En adaptant (un tout petit peu) la solution précédente cela donne :

$Document=@DesktopDir&"\tst_CRLF.txt"
$hnd=FileOpen($Document)
If $hnd=-1 Then exit 1
FileSetPos($hnd,-2,$FILE_END)
$ENDCHAR=FileRead($hnd,2)
$MESSAGE="Return not detected"
If $ENDCHAR==@CRLF Then $MESSAGE="Return detected"
ConsoleWrite($MESSAGE&@CRLF)
Exit 0

Simple et efficace. Merci Sylvanie.
Répondre