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 :)
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.