[.net2] utiliser la compression de fichiers native de windows2000/xp

0/5 (12 avis)

Vue 14 077 fois - Téléchargée 572 fois

Description

Bien, cette source est à but pédagogique.
Ici je vous montre comment utiliser la compression interne de fichiers dans Windows2000/XP.
Le code est vraiment très simple, vous verrez à quel point cela est facile d'utiliser cette feature.

Liens MSDN:
http://windowssdk.msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/fsctl_set_compression.asp
http://windowssdk.msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/fsctl_get_compression.asp

Plusieurs exemples sont présent:
-Compression d'un fichier
-Décompression d'un fichier
-Compression d'un répertoire et sous-répetoires
-Indication si un fichier est compressé ou non
-Indication si le lecteur supporte la compression de fichiers.

Source / Exemple :


Imports System.Runtime.InteropServices
Imports System.Text
Imports System.io

''' <summary>
''' Classe appelant la compression/décompression IO interne de NT.
''' </summary>
''' <remarks></remarks>
Public Class NTInternalCompression

    ''' <summary>Methodes de compression pouvant etre utilisées.</summary>
    Enum COMPRESS_METHOD
        _DEFAULT = 1
        _LZNT1 = 2
    End Enum

    ''' <summary>Compresse un fichier.</summary>
    ''' <param name="path">Chemin du fichier.</param>
    ''' <param name="method">Méthode de compression.</param>
    ''' <returns>Retourne le numéro d'erreur.
    ''' 0 = Pas d'erreur, la compression a réussi.
    ''' -2 = Le volume dans lequel se trouve le fichier ne supporte pas la compression de fichiers.</returns>
    Shared Function CompressFile(ByVal path As String, Optional ByVal method As COMPRESS_METHOD = COMPRESS_METHOD._LZNT1) As Integer

        If CompressionIsSupported(path.Substring(0, 3)) Then

            Dim hPath As IntPtr = NativeMethods.CreateFile("\\.\" & path, NativeMethods.GENERIC_ALL, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero)

            Dim iBytesReturned As Integer = 0

            NativeMethods.SetIoCompression(hPath, NativeMethods.FSCTL_SET_COMPRESSION, method, Marshal.SizeOf(GetType(Short)), IntPtr.Zero, 0, iBytesReturned, IntPtr.Zero)

            NativeMethods.CloseHandle(hPath)

        Else
            Return -2
        End If

        Return Marshal.GetLastWin32Error

    End Function

    ''' <summary>Décompresse un fichier.</summary>
    ''' <param name="path">Chemin à décompresser.</param>
    ''' <returns>Retourne le numéro d'erreur. Si 0 pas d'erreur.
    ''' -1 = Le fichier n'est pas compressé donc pas de décompression possible.
    ''' -2 = Le volume dans lequel se trouve le fichier ne supporte pas la compression de fichiers.</returns>
    Shared Function UnCompressFile(ByVal path As String) As Integer

        If CompressionIsSupported(path.Substring(0, 3)) Then

            If FileCompressionState(path) Then

                Dim hPath As IntPtr = NativeMethods.CreateFile("\\.\" & path, NativeMethods.GENERIC_ALL, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero)

                Dim iBytesReturned As Integer = 0

                NativeMethods.SetIoCompression(hPath, NativeMethods.FSCTL_SET_COMPRESSION, NativeMethods.COMPRESSION_FORMAT_NONE, Marshal.SizeOf(GetType(Short)), IntPtr.Zero, 0, iBytesReturned, IntPtr.Zero)

                NativeMethods.CloseHandle(hPath)

            Else
                Return -1
            End If

        Else
            Return -2
        End If

        Return Marshal.GetLastWin32Error

    End Function

    ''' <summary>Indique si le fichier est compressé.</summary>
    ''' <param name="path">Chemin du fichier.</param>
    ''' <returns>True si compressé; False non compressé.</returns>
    Shared Function FileCompressionState(ByVal path As String) As Boolean

        If CompressionIsSupported(path.Substring(0, 3)) Then

            Dim hPath As IntPtr = NativeMethods.CreateFile("\\.\" & path, NativeMethods.GENERIC_ALL, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero)

            Dim iMethod As Short = -1
            Dim iBytesReturned As Integer = 0

            NativeMethods.GetIoCompression(hPath, NativeMethods.FSCTL_GET_COMPRESSION, 0, 0, iMethod, Marshal.SizeOf(GetType(Short)), iBytesReturned, IntPtr.Zero)

            NativeMethods.CloseHandle(hPath)

            If iMethod <> 0 Then Return True Else Return False

        Else
            Return False
        End If

    End Function

    ''' <summary>Indique si la compression de fichiers est supporté sur le lecteur.</summary>
    ''' <param name="volume">Lettre du lecteur.</param>
    ''' <returns>True si réussi; False si échoué.</returns>
    Shared Function CompressionIsSupported(ByVal volume As String) As Boolean

        Dim szVolBuff As New StringBuilder
        Dim szFSBuff As New StringBuilder
        Dim flags As Integer = 0

        UnsafeMethods.GetVolumeInformation(volume, szVolBuff, 128, Nothing, Nothing, flags, szFSBuff, 128)

        If flags And UnsafeMethods.FS_FILE_COMPRESSION Then Return True Else Return False

    End Function

    ''' <summary>Compresse un répertoire.</summary>
    ''' <param name="path">Chemin du répertoire.</param>
    ''' <param name="recursive">Inclut les sous-répertoires.</param>
    ''' <param name="method">Méthode de compression.</param>
    Shared Sub CompressDirectory(ByVal path As String, ByVal recursive As Boolean, Optional ByVal method As COMPRESS_METHOD = COMPRESS_METHOD._LZNT1)

        If CompressionIsSupported(path.Substring(0, 3)) Then

            Dim hPath As IntPtr = NativeMethods.CreateFile("\\.\" & path, NativeMethods.GENERIC_ALL, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, NativeMethods.FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero)

            Dim iBytesReturned As Integer = 0

            NativeMethods.SetIoCompression(hPath, NativeMethods.FSCTL_SET_COMPRESSION, method, Marshal.SizeOf(GetType(Short)), IntPtr.Zero, 0, iBytesReturned, IntPtr.Zero)

            NativeMethods.CloseHandle(hPath)

            'ajoute l'attribut de compression aux répertoires
            For Each curdir As String In Directory.GetDirectories(path, "*", Convert.ToInt32(recursive))

                hPath = NativeMethods.CreateFile("\\.\" & curdir, NativeMethods.GENERIC_ALL, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, NativeMethods.FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero)

                NativeMethods.SetIoCompression(hPath, NativeMethods.FSCTL_SET_COMPRESSION, method, Marshal.SizeOf(GetType(Short)), IntPtr.Zero, 0, iBytesReturned, IntPtr.Zero)

                NativeMethods.CloseHandle(hPath)

            Next

            'Compresse tout les fichiers trouvés dans les répertoires
            Dim files As String() = Directory.GetFiles(path, "*", Convert.ToInt32(recursive))
            If files.Length > 0 Then

                For i As Integer = 0 To files.Length - 1

                    hPath = NativeMethods.CreateFile("\\.\" & files(i), NativeMethods.GENERIC_ALL, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero)

                    NativeMethods.SetIoCompression(hPath, NativeMethods.FSCTL_SET_COMPRESSION, method, Marshal.SizeOf(GetType(Short)), IntPtr.Zero, 0, iBytesReturned, IntPtr.Zero)

                    NativeMethods.CloseHandle(hPath)

                Next

            End If

        Else

#If DEBUG Then
            Debug.WriteLine("Compression non supporté sur ce lecteur.")
#End If

        End If

    End Sub

End Class

Conclusion :


Testé uniquement sous XP Pro.

Bonne prog à tous :)

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Baddante
Messages postés
33
Date d'inscription
mercredi 1 mars 2006
Statut
Membre
Dernière intervention
24 février 2008

23 août 2006 à 11:17
Attention la compression NT est uniquement réservé au stockage sur lecteur NTFS sous WinNT, si on envoi un fichier compressé par réseau ou modem, ou autres, il y a en interne une décompression du fichier puis l'envoi du fichier par le canal de communication choisi. Sur un lecteur de sauvegarde il y a également décompression de fichiers et dossiers NTFS puis le soft de backup vérifie si le lecteur supporte la compression Hardware optionnellement il y activation d'une compression software avant backup.

Pour les modems les réglages inclus nativement des algorithme de compression hard au niveau du modem.
cs_claudetom
Messages postés
115
Date d'inscription
jeudi 11 octobre 2001
Statut
Membre
Dernière intervention
15 octobre 2012

23 août 2006 à 00:39
Je trouve le code interessant et pratique pour la gestion d'envoi de multiple fichier d'un pc à un autre via une ligne téléphonique !!
En effet je compresse sur l'ordinateur maitre envoi sur le distant et ensuite décompresse.
En passant vous connaissez un source en VB.NET qui permet de créer une connexion RAS et se connecter avec sans l'utilisation d'une dll externe ?
Merci
cs_Patrice99
Messages postés
1221
Date d'inscription
jeudi 23 août 2001
Statut
Membre
Dernière intervention
9 septembre 2018

8 juin 2006 à 08:16
La réponse était donc : dans un but pédagogique, ce n'est pas si anodin que cela, car cela aide à comprendre ta source.
cs_eldim
Messages postés
956
Date d'inscription
lundi 30 mai 2005
Statut
Membre
Dernière intervention
21 août 2014
1
7 juin 2006 à 16:55
(je croix que son problème vient de la chaise longue....) pardon
cs_Willi
Messages postés
2375
Date d'inscription
jeudi 12 juillet 2001
Statut
Modérateur
Dernière intervention
15 décembre 2018
22
7 juin 2006 à 16:24
sa sert à faire parler les bavards....
bref sérieusement, sa ne t'intéresses pas de savoir comment le système tourne, comment utiliser les fonctions de l'API afin de reproduire certaines fonctionnalitées ?

Ce que j'ai présenté c'est ni plus ni moins qu'une démo reproduisant cette case à cocher de compression que tu retrouve dans les propriétés fichiers.
Afficher les 12 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.