Page 1 sur 1

[UDF] FileDeleteLines.au3 - Supprimer lignes dans fichier

Posté : mer. 15 déc. 2010 23:17
par Tlem
Voici un petit UDF de trois quatres fonctions :
  • La première fonction (_FileDeleteFirstLines) permet de supprimer un certain nombre de lignes au début d'un fichier donné.
  • La deuxième fonction (_FileDeleteLastLines) permet de supprimer un certain nombre de lignes à la fin d'un fichier donné.
  • La troisième fonction (_FileDeleteLines) permet de supprimer un certain nombre de lignes à l'intérieur d'un fichier donné.
  • La quatrième fonction (_FileCountLine2) permet de connaitre le nombre de ligne d'un fichier. Certes cette fonction existe déjà (_FileCountLine), mais sur un fichier de plus de 170 Mo, un message d'erreur d'allocation mémoire apparaît (Sur mon C2D XP SP3 2go RAM).
Il est possible de modifier ces fonctions pour les rendre plus simple grâce à un tableau, mais pour un fichier de très grosse taille (plus de 170 Mo), je doute que les temps de réponse soient correct et éventuellement il risque même d'y avoir des problèmes d'allocation mémoire. :roll:
Donc pour éviter ce genre de risques, je passe par une lecture/écriture sans utiliser (ou pratiquement pas) la mémoire. ;)
Si le fichier est plus petit que 170 Mo, alors j'utilise une version optimisée de la fonction, qui est nettement plus rapide en exécution.

Il reste une quatrième fonction que je voudrais écrire et qui permettrait d'indiquer des numéros de ligne à supprimer.
Je ferais ça sans doute prochainement (si je n'oublie pas).
C'est fait ...

Voici le code de l'UDF FileDeleteLines.au3 :

Code : Tout sélectionner

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include-once

; #FONCTION# ==============================================================================
; Nom ...........: _FileDeleteLines
; Description ...: Supprime une ou plusieurs lignes dans un fichier spécifié.
; Syntaxe .......: _FileDeleteLines($sFilePath, $iDelLines)
; Paramètres ....: $sFilePath - Chemin et nom du fichier à modifier
;                  $iDelLines - Numéro de ligne à supprimer (peut être un tableau croissant base-0 )
; Valeurs Retour : Succès - Retourne 1.
;                  Echec  - Retourne 0 et fixe l'erreur
;                           @Error - 1 = Problème de fichier
;                           @Error - 2 = Si $iDelLines n'est pas un nombre ou un tableau.
; Auteur ........: Tlem <tlem chez tuxolem point fr>
; Modifié .......:
; Remarques .....: Cette fonction n'est probablement pas optimisée pour des petits fichiers,
;                  mais elle fonctionne sur des fichiers de grosse taille.
; Apparenté .....:
; Lien ..........:
; Exemple .......:
; =========================================================================================
Func _FileDeleteLines($sFilePath, $iDelLines = 0)
    ; Test si $iDelLines est un tableau ou un nombre.
    If Not IsNumber($iDelLines) And Not IsArray($iDelLines) Then
        Return SetError(2, 0, 0)
    EndIf

    ; Ouverture du fichier source
    Local $hFilePath = FileOpen($sFilePath, 0)
    If $hFilePath = -1 Then Return SetError(1, 0, 0)

    ; Déclaration des variables utilisées dans la fonction
    Local $sTmpFile = @TempDir & "\tmpfile.txt"
    Local $ArrayIndex = 0
    Local $sLineTxt = ""
    Local $iLine = 0
    Local $i

    ; Ouverture du fichier temporaire
    Local $hFiletmp = FileOpen($sTmpFile, 2)
    If $hFiletmp = -1 Then Return SetError(1, 0, 0)

    ; Cas ou $iDelLines est un nombre
    If IsNumber($iDelLines) Then
        ; Boucle d'écriture des lignes
        While 1
            $iLine += 1
            $sLineTxt = FileReadLine($hFilePath)
            If @error = -1 Then ExitLoop
            ; Sauf la ligne $iDelLines
            If $iLine <> $iDelLines Then FileWriteLine($hFiletmp, $sLineTxt)
        WEnd
    EndIf

    ; Cas ou $iDelLines est un tableau
    If IsArray($iDelLines) Then
        ; Vérifie si $iDelLines est un tableau croissant
        If Not IsNumber($iDelLines[0]) Then SetError(2, 0, 0)
        For $i = 1 to UBound($iDelLines) -1
            If Not IsNumber($iDelLines[$i]) And $iDelLines[$i] < $iDelLines[$i - 1] Then
                SetError(2, 0, 0)
            EndIf
        Next

        ; Boucle d'écriture des lignes
        While 1
            $iLine += 1
            $sLineTxt = FileReadLine($hFilePath)
            If @error = -1 Then ExitLoop
            ; Sauf des lignes contenues dans le tableau $iDelLines
            If $iLine <> $iDelLines[$ArrayIndex] Then
                FileWriteLine($hFiletmp, $sLineTxt)
            Else
                $ArrayIndex += 1
            EndIf
        WEnd

    EndIf

    ;Fermeture des fichiers
    FileClose($hFilePath)
    FileClose($hFiletmp)

    ; Si le fichier temporaire existe (> Oko) alors on le copie à la place du fichier d'origine.
    If FileExists($sTmpFile) And FileGetSize($sTmpFile) > 0 Then
        If Not FileMove($sTmpFile, $sFilePath, 1) Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf

    Return 1
EndFunc   ;==>_FileDeleteLines

; #FONCTION# ==============================================================================
; Nom ...........: _FileDeleteFirstLines
; Description ...: Supprime les premières lignes du fichier spécifié.
; Syntaxe .......: _FileDeleteFirstLines($sFilePath, $iDelLines)
; Parametres ....: $sFilePath - Chemin et nom du fichier à modifier
;                  $iDelLines - Nombre de lignes à supprimer
; Valeurs Retour : Succès - Retourne 1.
;                  Echec  - Retourne 0 est fixe l'erreur
; Auteur ........: Tlem <tlem chez tuxolem point fr>
; Modifié .......:
; Remarques .....: Cette fonction n'est probablement pas optimisée pour des petits fichiers,
;                  mais elle fonctionne sur des fichiers de grosse taille.
; Apparenté .....:
; Lien ..........:
; Exemple .......:
; =========================================================================================
Func _FileDeleteFirstLines($sFilePath, $iDelLines = 0)
    ; Ouverture du fichier source
    Local $hFilePath = FileOpen($sFilePath, 0)
    If $hFilePath = -1 Then Return SetError(1, 0, 0)

    ; Déclaration des variables utilisées dans la fonction
    Local $sTmpFile = @TempDir & "\tmpfile.txt"
    Local $sLineTxt = ""
    Local $iLine = 0

    ; Ouverture du fichier temporaire
    Local $hFiletmp = FileOpen($sTmpFile, 2)
    If $hFiletmp = -1 Then Return SetError(1, 0, 0)

    ; Boucle d'écriture des lignes
    While 1
        $iLine += 1
        $sLineTxt = FileReadLine($hFilePath)
        If @error = -1 Then ExitLoop
        If $iLine > $iDelLines Then FileWriteLine($hFiletmp, $sLineTxt)
    WEnd

    ;Fermeture des fichiers
    FileClose($hFilePath)
    FileClose($hFiletmp)

    ; Si le fichier temporaire existe (> Oko) alors on le copie à la place du fichier d'origine.
    If FileExists($sTmpFile) And FileGetSize($sTmpFile) > 0 Then
        If Not FileMove($sTmpFile, $sFilePath, 1) Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf

    Return 1
EndFunc   ;==>_FileDeleteFirstLines

; #FUNCTION# ==============================================================================
; Name...........: _FileDeleteLastLines
; Description ...: Supprime les dernières lignes du fichier spécifié.
; Syntaxe .......: _FileDeleteLastLines($sFilePath, $iDelLines)
; Parametres ....: $sFilePath - Chemin et nom du fichier à modifier
;                  $iDelLines - Nombre de lignes à supprimer
; Valeurs Retour : Succès - Retourne 1.
;                  Echec  - Retourne 0 et fixe l'erreur
; Requis   ......: _FileCountLines2
; Auteur ........: Tlem <tlem chez tuxolem point fr>
; Modifié .......:
; Remarques .....: Cette fonction n'est probablement pas optimisée pour des petits fichiers,
;                  mais elle fonctionne sur des fichiers de grosse taille.
; Apparenté .....:
; Lien ..........:
; Exemple .......:
; =========================================================================================
Func _FileDeleteLastLines($sFilePath, $iDelLines = 0)
    ; Ouverture du fichier source
    Local $hFilePath = FileOpen($sFilePath, 0)
    If $hFilePath = -1 Then Return SetError(1, 0, 0)

    ; Déclaration des variables utilisées dans la fonction
    Local $sTmpFile = @TempDir & "\tmpfile.txt"
    Local $sLineTxt = ""

    ; Ouverture du fichier temporaire
    Local $hFiletmp = FileOpen($sTmpFile, 2)
    If $hFiletmp = -1 Then Return SetError(1, 0, 0)

    ; Comptage du nombre de ligne du fichier
    Local $iFileline = _FileCountLines2($sFilePath) - $iDelLines
    Local $iLine = 1

    ; Boucle d'écriture des lignes
    While $iLine <= $iFileline
        $sLineTxt = FileReadLine($hFilePath)
        If @error = -1 Then ExitLoop
        FileWriteLine($hFiletmp, $sLineTxt)
        $iLine += 1
    WEnd

    ;Fermeture des fichiers
    FileClose($hFilePath)
    FileClose($hFiletmp)

    ; Si le fichier temporaire existe (> Oko) alors on le copie à la place du fichier d'origine.
    If FileExists($sTmpFile) And FileGetSize($sTmpFile) > 0 Then
        If Not FileMove($sTmpFile, $sFilePath, 1) Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf

    Return 1
EndFunc   ;==>_FileDeleteLastLines

; #FUNCTION# ==============================================================================
; Nom ...........: _FileCountLines2
; Description ...: Retourne le nombre de lignes dans le fichier spécifié.
; Syntaxe .......: _FileCountLines2($sFilePath)
; Paramètres ....: $sFilePath - Chemin et nom du fichier à lire
; Valeurs Retour : Succès - Retourne le nombre de lignes dans le fichier.
;                  Echec  - Retourne 0 et fixe l'erreur
;                  @Error  - 0 = Pas d'erreur.
;                  |1 = Le fichier ne peut être ouvert ou trouvé.
; Auteur ........: Tlem <tlem chez tuxolem point fr>
; Modifié .......:
; Remarques .....: Cette fonction est sera légèrement plus lente que la fonction d'origine, si le fichier
;                  dépasse 179 639 503 octets sinon elle sera nettement plus rapide.
;                  Ne retourne pas d'erreur d'allocation mémoire même si le fichier est > 180Mo.
; Apparenté .....:
; Lien ..........:
; Exemple .......:
; =========================================================================================
Func _FileCountLines2($sFilePath)

    ; Ouverture du fichier
    Local $hFile = FileOpen($sFilePath, 0)
    If $hFile = -1 Then Return SetError(1, 0, 0)

    ; Récupération de la taille du fichier - 1
    Local $N = FileGetSize($sFilePath) - 1
    If @error Or $N = -1 Then Return SetError(1, 0, 0)

    ; La taille de lecture d'un fichier par un FileRead ne doit pas dépasser 183 145 242 octets,
    ; sinon, il y à une erreur d'allocation mémoire.
    ; Après plusieurs test, 179 639 503 octets semble être la taille maximale dans certains cas particuliers.
    If $N + 1 <= 179639503 Then
        ; Calcul du nombre de lignes.
        Local $nbLines = StringLen(StringAddCR(FileRead($hFile, $N))) - $N + 1

        ; Fermeture du fichier
        FileClose($hFile)
        Return $nbLines
    EndIf

    Local $nbLine = 0

    ; Boucle de lecture du fichier
    While 1
        FileReadLine($hFile)
        If @error = -1 Then ExitLoop
        $nbLine += 1
    WEnd

    ; Fermeture du fichier
    FileClose($hFile)

    Return $nbLine
EndFunc   ;==>_FileCountLines2
Script d'exemple :

Code : Tout sélectionner

#include 'FileDeleteLines.au3'

; ##### _FileCountLines2 #####
; Compte le nombre de lignes du fichier.
_CreateTestFile()
MsgBox(0, 'Fichier à tester :', FileRead("Test.txt"))
MsgBox(0, 'Nombre de ligne :', _FileCountLines2("Test.txt"))


; ##### _FileDeleteLines #####
; Suppression  de toutes les lignes paires du fichier.
_CreateTestFile()
MsgBox(0, 'Avant modification _FileDeleteLines :', FileRead("Test.txt"))
Global $aLine[6] = [2, 4, 6, 8, 10]
_FileDeleteLines("Test.txt", $aLine)
MsgBox(0, 'Après modification _FileDeleteLines :', FileRead("Test.txt"))


; ##### _FileDeleteFirstLines #####
; Suppression  des 3 premières lignes du fichier.
_CreateTestFile()
MsgBox(0, 'Avant modification _FileDeleteFirstLines :', FileRead("Test.txt"))
_FileDeleteFirstLines("Test.txt", 3)
MsgBox(0, 'Après modification _FileDeleteFirstLines :', FileRead("Test.txt"))


; ##### _FileDeleteLastLines #####
; Suppression  des 3 dernières lignes du fichier.
_CreateTestFile()
MsgBox(0, 'Avant modification _FileDeleteLastLines :', FileRead("Test.txt"))
_FileDeletelastLines("Test.txt", 3)
MsgBox(0, 'Après modification _FileDeleteLastLines :', FileRead("Test.txt"))


Func _CreateTestFile()
    Local $hFile = FileOpen("Test.txt", 2)
    If $hFile = -1 Then
        MsgBox(0, "Erreur", "Impossible de créer le fichier.")
        Exit
    EndIf
    FileWrite($hFile, "Ligne 1" & @CRLF & "Ligne 2" & @CRLF & "Ligne 3" & @CRLF & "Ligne 4" & _
            @CRLF & "Ligne 5" & @CRLF & "Ligne 6" & @CRLF & "Ligne 7" & @CRLF & "Ligne 8" & _
            @CRLF & "Ligne 9" & @CRLF & "Ligne 10")
    FileClose($hFile)
EndFunc   ;==>_CreateTestFile

Re: [UDF] Supprimer des lignes dans un fichier

Posté : jeu. 16 déc. 2010 18:34
par Colin117
Super cet UDF merci ça va beaucoup me servir prochainement.

Re: [UDF] Supprimer des lignes dans un fichier

Posté : ven. 17 déc. 2010 21:28
par Tlem
Mise à jour du premier message.
- Ajout de la fonction _FileDeleteLines
- Ajout de commentaires sur le code.
- Mise en Français :roll: de l'UDF ...

Prochainement, ajout d'exemples.
C'est fait ... :wink:

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichier

Posté : ven. 31 déc. 2010 18:33
par Tlem
Mise à jour du premier message :
- Optimisation de la fonction _FileCountLines2. Voir les commentaires de la fonction pour plus d'explications.

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

Posté : sam. 23 avr. 2011 22:53
par karime1
bonjours,
j'arrive pas a utiliser cette fonction. voici le message de la S.check
(29,43) : ERROR: FileOpen() [built-in] called with wrong number of args.
Local $hFilePath = FileOpen($sFilePath)

est ce que vous avez une idée d'ou vien le prob?
a la 29eme ligne et a deux autre y'a "fileopen" avec seulement une seule et unique option indiquer alors qu'elle requiert deux! il faut lui ajouter ,0)
donc voila le func Checké :D

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

Posté : dim. 24 avr. 2011 11:04
par Tlem
karime1 a écrit :y'a "fileopen" avec seulement une seule et unique option indiquer alors qu'elle requiert deux! il faut lui ajouter ,0)
Encore une fois, manque de lecture de la documentation. :evil:
Il ne manque pas de paramètre, cette manière d'écrire était voulue car si vous aviez lu la documentation :
FileOpen
Parameters
[optional] Mode to open the file in.
Can be a combination of the following:
0 = Read mode (default)
1 = Write mode (append to end of file)
2 = Write mode (erase previous contents)
8 = Create directory structure if it doesn't exist (See Remarks).
16 = Force binary mode (See Remarks).
32 = Use Unicode UTF16 Little Endian reading and writing mode. Reading does not override existing BOM.
64 = Use Unicode UTF16 Big Endian reading and writing mode. Reading does not override existing BOM.
128 = Use Unicode UTF8 (with BOM) reading and writing mode. Reading does not override existing BOM.
256 = Use Unicode UTF8 (without BOM) reading and writing mode.
16384 = When opening for reading and no BOM is present, use full file UTF8 detection. If this is not used then only the initial part of the file is checked for UTF8.
The folder path must already exist (except using mode '8' - See Remarks).
Donc avant d'affirmer des choses, renseignez vous avant !

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

Posté : dim. 24 avr. 2011 19:49
par karime1
meme si c'est optional ça marche pas sans. je cherche pas a ce que tu me crois, je veux juste aider les gens qui ont eu/ auront le meme prob.
et aussi tu devrai remplacer
"(_DeleteFirstLines) permet de... (_DeleteLastLines) permet" par
"(_FileDeleteFirstLines) permet de... (_FileDeleteLastLines) permet"
(au debut du 1er message)

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

Posté : dim. 24 avr. 2011 22:27
par Tlem
Je trouve étrange que cela ne fonctionne pas chez vous alors que ca fonctionne parfaitement sur 3 de mes plateformes !!!

Avez-vous la dernière version de AutoIt ?
Quel est le code qui vous donne ce messages d'erreur, car mon code d'exemple fonctionne lui aussi très bien. :shock:

Ok pour la modif sur le nom des fonctions (un reliquat des premières versions ...). :|

Edit : N'étant pas aussi fermé qu'une huitre, je concède l'ajout de l'option 0 dans le FileOpen bien qu'en réalité elle n'est pas obligatoire (cela est spécifié dans la documentation).
Mais afin d'éviter toute polémique inutile, je préfère la spécifié.
Merci de votre attention.

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

Posté : mer. 04 mai 2011 07:38
par karime1
ouais c'était ça le prob. bon j'ai fait maintenant la mise a jour mais un autre prob est apparu: j'ai essayé de transformer la filedeletefirstlines a une qui cherche elle ou s'arrêter de supprimer.explication:
robot!
je veux que tu efface toute les ligne jusqu'à ce que tu arrive a la ligne ou est écrit "Chapitre 2"
dans un fichier txt ou il y'a "Chapitre1"& @CRLF &" bla bla bla"& @CRLF &"Chapitre 2"& @CRLF &" bla bla bla Chap ..."
alors voila

Code : Tout sélectionner

#Include <FileDeleteLines.au3>
Global $File="D:\Lol.txt"
$TotalLineNumber=_FileCountLines2($File)
$FileData = FileOpen($File)
For $LineNumber=1 To $TotalLineNumber Step 1
    $LineData = FileReadLine($FileData,$LineNumber)
    FileClose($File)
    If @error = -1 Then Exit 20
    If $LineData="Chapitre 2" Then
        _FileDeleteFirstLines($File,$LineNumber-1)
        ExitLoop
    EndIf
Next
mais tout ce qu'il fait c'est effacer le fichier!
(et désoler pour la réponse en retard j'essayai de résoudre moi même le prob)

Re: [UDF] FileDeleteLines.au3 - Supprimer lignes dans fichie

Posté : mer. 04 mai 2011 08:33
par Tlem
Cette section n'est pas la bonne pour les demandes d'aide.