53 votes

Flux de données alternatifs NTFS - .NET

Comment créer / supprimer / lire / écrire / NTFS des flux de données alternatifs à partir de .NET?

S'il n'y a pas de support .NET natif, quelle API Win32 utiliserais-je? Aussi, comment pourrais-je les utiliser, car je ne pense pas que cela soit documenté?

33voto

JaredPar Points 333733

Voici une version pour C #

 using System.Runtime.InteropServices;

class Program
{
    static void Main(string[] args)
    {
        var mainStream = NativeMethods.CreateFileW(
            "testfile",
            NativeConstants.GENERIC_WRITE,
            NativeConstants.FILE_SHARE_WRITE,
            IntPtr.Zero,
            NativeConstants.OPEN_ALWAYS,
            0,
            IntPtr.Zero);

        var stream = NativeMethods.CreateFileW(
            "testfile:stream",
            NativeConstants.GENERIC_WRITE,
            NativeConstants.FILE_SHARE_WRITE,
            IntPtr.Zero,
            NativeConstants.OPEN_ALWAYS,
            0,
            IntPtr.Zero);
    }
}

public partial class NativeMethods
{

    /// Return Type: HANDLE->void*
    ///lpFileName: LPCWSTR->WCHAR*
    ///dwDesiredAccess: DWORD->unsigned int
    ///dwShareMode: DWORD->unsigned int
    ///lpSecurityAttributes: LPSECURITY_ATTRIBUTES->_SECURITY_ATTRIBUTES*
    ///dwCreationDisposition: DWORD->unsigned int
    ///dwFlagsAndAttributes: DWORD->unsigned int
    ///hTemplateFile: HANDLE->void*
    [DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW")]
    public static extern System.IntPtr CreateFileW(
        [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, 
        uint dwDesiredAccess, 
        uint dwShareMode, 
        [InAttribute()] System.IntPtr lpSecurityAttributes, 
        uint dwCreationDisposition, 
        uint dwFlagsAndAttributes, 
        [InAttribute()] System.IntPtr hTemplateFile
    );

}


public partial class NativeConstants
{

    /// GENERIC_WRITE -> (0x40000000L)
    public const int GENERIC_WRITE = 1073741824;

    /// FILE_SHARE_DELETE -> 0x00000004
    public const int FILE_SHARE_DELETE = 4;

    /// FILE_SHARE_WRITE -> 0x00000002
    public const int FILE_SHARE_WRITE = 2;

    /// FILE_SHARE_READ -> 0x00000001
    public const int FILE_SHARE_READ = 1;

    /// OPEN_ALWAYS -> 4
    public const int OPEN_ALWAYS = 4;
}
 

16voto

Zack Elan Points 821

Il n'est pas natif .NET de l'aide pour eux. Vous devez utiliser P/Invoke pour appeler le natif Win32 méthodes.

Pour les créer, de les appeler CreateFile avec un chemin comme filename.txt:streamname. Si vous utilisez l'appel d'interopérabilité qui retourne un SafeFileHandle, vous pouvez l'utiliser pour construire un FileStream que vous pouvez ensuite lire & écrire.

Pour lister les flux qui existent sur un fichier, utilisez FindFirstStreamW et FindNextStreamW (qui n'existent que sur le Serveur 2003 et plus tard - pas XP).

Je ne crois pas que vous pouvez supprimer un flux de données, sauf en copiant le reste du fichier, et en laissant au large de l'un des flux. Réglage de la longueur de 0 peut aussi travailler, mais je n'ai pas essayé.

Vous pouvez également avoir d'autres flux de données sur un répertoire. Leur accès est le même qu'avec les fichiers - C:\some\directory:streamname.

Les flux de compression, de cryptage et de rareté fixé sur eux indépendante de la valeur par défaut de flux.

15voto

Simon Mourier Points 49585

Ce package de nugets CodeFluent Runtime Client comprend (entre autres utilitaires) une classe NtfsAlternateStream qui prend en charge les opérations de création / lecture / mise à jour / suppression / énumération.

11voto

SeeR Points 1017

Vous avez prêt à utiliser la bibliothèque ici sur codeproject

4voto

Otávio Décio Points 44200

Pas en .NET:

http://support.microsoft.com/kb/105763

 #include <windows.h>
   #include <stdio.h>

   void main( )
   {
      HANDLE hFile, hStream;
      DWORD dwRet;

      hFile = CreateFile( "testfile",
                       GENERIC_WRITE,
                    FILE_SHARE_WRITE,
                                NULL,
                         OPEN_ALWAYS,
                                   0,
                                NULL );
      if( hFile == INVALID_HANDLE_VALUE )
         printf( "Cannot open testfile\n" );
      else
          WriteFile( hFile, "This is testfile", 16, &dwRet, NULL );

      hStream = CreateFile( "testfile:stream",
                                GENERIC_WRITE,
                             FILE_SHARE_WRITE,
                                         NULL,
                                  OPEN_ALWAYS,
                                            0,
                                         NULL );
      if( hStream == INVALID_HANDLE_VALUE )
         printf( "Cannot open testfile:stream\n" );
      else
         WriteFile(hStream, "This is testfile:stream", 23, &dwRet, NULL);
   }
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X