Géré .NET Équivalent à CreateFile & WriteFile de WinBase (kernel32.dll)
Je travaille avec un héritage format de fichier.
Le fichier est créé à l'aide de C++ qui utilise la WinBase.h CreateFile() & WriteFile() les fonctions (qui se trouve dans la kernel32.dll).
J'ai été à l'aide de P/Invoke interop pour accéder à ces fonctions natives comme suit:
[DllImport("kernel32.dll")]
public static extern bool WriteFile(
IntPtr hFile,
byte[] lpBuffer,
uint nNumberOfBytesToWrite,
out uint lpNumberOfBytesWritten,
[In] ref NativeOverlapped lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteFileEx(
IntPtr hFile,
byte[] lpBuffer,
uint nNumberOfBytesToWrite,
[In] ref NativeOverlapped lpOverlapped,
WriteFileCompletionDelegate lpCompletionRoutine);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFile(
string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
public delegate void WriteFileCompletionDelegate(
UInt32 dwErrorCode,
UInt32 dwNumberOfBytesTransfered,
ref NativeOverlapped lpOverlapped);
Le problème, c'est quand je l'appelle WriteFile(), le fichier est toujours remplacé par l'instance d'appel.
Préférable je voudrais utiliser un compatible .NET équivalent, ce qui me permettrait de produire exactement le même format de sortie.
Le code C++ ressemble à ceci: (TRAVAIL)
HANDLE hFile = CreateFile(sFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, &someVar1, sizeof(bool), &dwWritten, NULL);
WriteFile(hFile, &someVar1, sizeof(long), &dwWritten, NULL);
WriteFile(hFile, &someVar2, sizeof(bool), &dwWritten, NULL);
WriteFile(hFile, sStr.GetBuffer(0), dwStrLen*sizeof(TCHAR), &dwWritten, NULL);
CloseHandle(hFile);
Le C# est comme suit: (REMPLACE les PRÉCÉDENTES ÉCRIRE i.e. la volonté du fichier de sortie ne contiendra que les "T")
{
var hFile = COMFileOps2.CreateFile(FILE_NAME, (uint) COMFileOps2.FILE_GENERIC_WRITE,
COMFileOps2.FILE_SHARE_WRITE, IntPtr.Zero, COMFileOps2.CREATE_ALWAYS,
COMFileOps2.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
var natOverlap = new NativeOverlapped();
COMFileOps2.WriteFileEx(hFile, new byte[] {(byte) 't'}, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'e' }, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'s' }, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'T' }, 1, ref natOverlap, Callback);
COMFileOps2.CloseHandle(hFile);
}
private static void Callback(uint dwerrorcode, uint dwnumberofbytestransfered, ref NativeOverlapped lpoverlapped)
{
throw new NotImplementedException();
}
Mise à JOUR: Le code C# suivant va écrire "Test":
uint written;
uint position = 0;
var natOverlap0 = new NativeOverlapped();
COMFileOps.WriteFile(hFile, new byte[] {(byte) 'T'}, 1, out written, ref natOverlap0);
position += written;
var natOverlap1 = new NativeOverlapped {OffsetLow = (int) position};
COMFileOps.WriteFile(hFile, new byte[] { (byte)'e' }, 1, out written, ref natOverlap1);
position += written;
var natOverlap2 = new NativeOverlapped { OffsetLow = (int)position };
COMFileOps.WriteFile(hFile, new byte[] { (byte)'s' }, 1, out written, ref natOverlap2);
position += written;
var natOverlap3 = new NativeOverlapped { OffsetLow = (int)position };
COMFileOps.WriteFile(hFile, new byte[] { (byte)'t' }, 1, out written, ref natOverlap3);
COMFileOps.CloseHandle(hFile);
Grâce.
OriginalL'auteur holsee | 2010-03-22
Vous devez vous connecter pour publier un commentaire.
WriteFileEx seulement s'exécute de façon asynchrone, vous devez fournir une instance DISTINCTE de chevaucher pour chaque appel en attente, et vous devez le programme d'installation recouvrement des membres, tels que l'offset du fichier. Ensuite, vous ne pouvez pas appeler CloseHandle jusqu'à ce que toutes les opérations de finition. Et à l'aide d'une variable locale pour se CHEVAUCHAIENT et le laisser aller hors de portée? Vos données écrasés est le moins de choses qui peuvent mal se passer avec le code vous montrer.
C'est pour ça que votre code ne fonctionne pas. Je ne sais pas pourquoi vous avez changé de WriteFile pour WriteFileEx en premier lieu. En outre, l'appel de l'API Win32 en C# est très gênant, bien que parfois nécessaire. Mais d'abord voir si l' .NET Fichier Api de faire ce que vous avez besoin.
Depuis .NET Fichier Api ont tendance à travailler avec des chaînes de caractères (textmode, de regarder pour le saut de ligne conversions et par exemple) ou des tableaux d'octets, vous avez besoin pour transformer votre autres variables en byte[]. Le BitConverter classe est votre ami ici.
OriginalL'auteur Ben Voigt
Vous n'avez pas expliquer quel format que vous essayez de manipuler, mais n'est pas Fichier.WriteAllText suffisant?
Pour les fichiers binaires vous pouvez utiliser Fichier.WriteAllBytes:
OriginalL'auteur Darin Dimitrov
Regarder la
System.IO.File
etSystem.IO.FileInfo
classes ils fournissent à la fois les méthodes que vous recherchez.OriginalL'auteur AxelEckenberger
Il n'y a rien de particulier à propos de la crue des appels d'API. Juste obtenir un Système.IO.FileStream et appel d'Écrire sur lui. (Une manière d'obtenir la FileStream est d'abord acquérir un Système.IO.Fichier en premier.
OriginalL'auteur Yuliy