The Microsoft Caching Application Block contains a useful internal class that can be used to write/read meta-data to file on NTFS files, as I had to do recently.  Part of the app block is the MemoryMappedFileHelper.cs file which contains a ton of P/Invoke definitions including the Win32 function CreateFile, along with all it's related enums.  Here is one of the wrapper methods I created:

private static readonly string _fileDataStreamFormat="{0}:{1}";
public static byte[] GetAlternateDataStream(string fileName, string dataStreamName)
{
    if(dataStreamName.Trim().Length==0)
        throw new ArgumentException("dataStreamName must not be an empty string", "dataStreamName");
    string filePath = Path.GetFullPath(fileName);
    string adsPath = string.Format(_fileDataStreamFormat, filePath, dataStreamName);
    if(!File.Exists(filePath))
        throw new FileNotFoundException(string.Format("The file path '{0}' cannot be found.  
Please check the file location and provide full path info", filePath)); IntPtr hFile = MemoryMappedFileHelper.CreateFile(adsPath , Win32FileAccess.GENERIC_READ , Win32FileShare.FILE_SHARE_READ , IntPtr.Zero , Win32FileMode.OPEN_ALWAYS , 0 , IntPtr.Zero); FileStream stream = new FileStream(hFile, FileAccess.Read); int length = Convert.ToInt32(stream.Length); byte[] streamValues = new byte[length]; try { int totalRead=0; while(totalRead<length) { totalRead+=stream.Read(streamValues, totalRead, length-totalRead); } } finally { stream.Close(); } return streamValues; }
This method takes in the file name and the name for the data stream and returns the byte[] data returned by the file system. You just have to de-serialize it into whatever form it takes: text, array or even .NET object graph. I have created several other methods to write to the stream and also to obtain a .NET FileStream to the alternate data stream (but I'll spare you the code dump here and upload them in zip format in the near future).