FilePut ne ajoute pas les deux octets de longueur lors de l’écriture d’une chaîne dans un fichier binary à partir de C #. FilePutObject lève des exceptions sur les classes / structures

J’ai une application qui doit être compatible en lecture et en écriture avec un fichier binary VB6. J’ai entendu parler de la classe Microsoft.VisualBasic.FileSystem et j’essaie d’écrire une structure dans le fichier.

 FileSystem.FileOpen(file, "test.bin", Microsoft.VisualBasic.OpenMode.Binary); FileSystem.FilePut(file, patch.intTest); FileSystem.FilePut(file, patch.dateTest); FileSystem.FilePut(file, patch.ssortingngTest, SsortingngIsFixedLength: false); FileSystem.FilePut(file, patch.boolTest); 

Tout écrit correctement si je mets chaque élément individuellement sauf la chaîne. Lorsque l’application VB6 écrit la chaîne, elle ajoute deux octets de longueur, mais pas mon code.

Dans le MSDN, il est indiqué que le mode binary supprime les octets de longueur, sauf s’il se trouve dans une structure. Définir SsortingngIsFixedLength sur true devrait le faire, mais il semble que le mode binary dépasse ce paramètre.

J’essaie d’utiliser FilePutObject et d’essayer de passer une struct ou une classe (c’est ce que le msdn dit que vous devez faire pour que les octets apparaissent) il lève l’exception

 System.ArgumentException occurred Message=File I/O with type 'PatchFileStructure' is not valid. Source=Microsoft.VisualBasic StackTrace: at Microsoft.VisualBasic.FileSystem.FilePutObject(Int32 FileNumber, Object Value, Int64 RecordNumber) at SandboxConsole.Sandbox.Main(Ssortingng[] args) in E:\Code\Sandbox Console\SandboxConsole\Program.cs:line 41 InnerException: 

Code complet

 using System; using Microsoft.VisualBasic; namespace SandboxConsole { static class Sandbox { public struct PatchFileStructure { public Int32 intTest { get; set; } public DateTime dateTest { get; set; } public ssortingng ssortingngTest { get; set; } public bool boolTest { get; set; } } public static void Main(params ssortingng[] args) { var patch = new PatchFileStructure() { intTest = 5, dateTest = new DateTime(1999, 1, 1, 1, 1, 1), ssortingngTest = "Test Name", boolTest = true, }; int file = FileSystem.FreeFile(); FileSystem.Kill("test.bin"); FileSystem.FileOpen(file, "test.bin", Microsoft.VisualBasic.OpenMode.Binary); FileSystem.FilePutObject(file, patch); //FileSystem.FilePut(file, patch.intTest); //FileSystem.FilePut(file, patch.dateTest); //FileSystem.FilePut(file, patch.ssortingngTest, SsortingngIsFixedLength: false); //FileSystem.FilePut(file, patch.boolTest); FileSystem.FileClose(file); } } } 

Voici mes deux fichiers que je compare. Des espaces sont ajoutés à la version c # pour illustrer le problème.

 vb6 - 05 00 00 00 24 F6 1D 5B 21 A8 E1 40 09 00 54 65 73 74 20 4E 61 6D 65 FF FF C# - 05 00 00 00 24 F6 1D 5B 21 A8 E1 40 54 65 73 74 20 4E 61 6D 65 FF FF 

Si j’essaie de lire le fichier vb6 à partir du C #, tout fonctionne correctement, à l’exception de la chaîne qui renvoie null.

FilePutObject semble être beaucoup plus détaillé et écrire plus de métadonnées que nécessaire, principalement pour les variantes.
Avez-vous essayé juste:

 FileSystem.FilePut(file, patch); 

Ceci utilise la surcharge “ValueType”.

Vous pouvez écrire la longueur explicitement avant la chaîne:

 FileSystem.FilePut(file, patch.ssortingngTest.Lenght.ToInt16); FileSystem.FilePut(file, patch.ssortingngTest, SsortingngIsFixedLength: false); 

Changer en:

 FileSystem.FilePut(file, patch.ssortingngTest, SsortingngIsFixedLength: false); 

Le système n’écrit pas le préfixe de longueur car vous lui indiquez que la chaîne a une longueur fixe.