FilePut не добавляет два байта длины при записи строки в двоичный файл из C #.FilePutObject генерирует исключения для классов / структур - PullRequest
2 голосов
/ 09 ноября 2011

У меня есть приложение, которое должно быть совместимым как для чтения, так и для записи, с двоичным файлом VB6.Я узнал о классе Microsoft.VisualBasic.FileSystem и пытаюсь записать структуру в файл.

FileSystem.FileOpen(file, "test.bin", Microsoft.VisualBasic.OpenMode.Binary);

FileSystem.FilePut(file, patch.intTest);
FileSystem.FilePut(file, patch.dateTest);
FileSystem.FilePut(file, patch.stringTest, StringIsFixedLength: false);
FileSystem.FilePut(file, patch.boolTest);

Все пишет правильно, если я помещаю каждый элемент отдельно, кроме строки.Когда приложение VB6 записывает строку, оно добавляет два байта длины, мой код этого не делает.

В MSDN он говорит, что двоичный режим удаляет байты длины, если он не находится в структуре.Установка StringIsFixedLength в true должна сделать это, но, похоже, что бинарный режим переопределяет этот параметр.

Я пытаюсь использовать FilePutObject и пытаюсь передать структуру или класс (это то, что MSDN говорит вамнужно сделать, чтобы байты показывались) выдает исключение

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(String[] args) in E:\Code\Sandbox Console\SandboxConsole\Program.cs:line 41
  InnerException: 

Полный код

using System;
using Microsoft.VisualBasic;

namespace SandboxConsole
{
    static class Sandbox
    {
        public struct PatchFileStructure
        {
            public Int32 intTest { get; set; }
            public DateTime dateTest { get; set; }
            public string stringTest { get; set; }
            public bool boolTest { get; set; }
        }

        public static void Main(params string[] args)
        {
            var patch = new PatchFileStructure()
            {
                intTest = 5,
                dateTest = new DateTime(1999, 1, 1, 1, 1, 1),
                stringTest = "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.stringTest, StringIsFixedLength: false);
            //FileSystem.FilePut(file, patch.boolTest);

            FileSystem.FileClose(file);
        }
    }
}

Вот мои два файла, которые я сравниваю.Пробелы добавляются в версию c # для иллюстрации проблемы.

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

Если я пытаюсь прочитать файл vb6 из C #, все работает хорошо, кроме строки, которая возвращает ноль.

Ответы [ 3 ]

3 голосов
/ 10 ноября 2011

FilePutObject кажется намного более многословным и записывает больше метаданных, чем необходимо, в первую очередь для вариантов.
Вы пробовали только:

FileSystem.FilePut(file, patch);

Используется перегрузка "ValueType".

2 голосов
/ 10 ноября 2011

Вы можете явно указать длину перед строкой:

FileSystem.FilePut(file, patch.stringTest.Lenght.ToInt16);
FileSystem.FilePut(file, patch.stringTest, StringIsFixedLength: false);
1 голос
/ 09 ноября 2011

Изменить на:

FileSystem.FilePut(file, patch.stringTest, StringIsFixedLength: false);

Система не записывает префикс длины, потому что вы говорите, что строка имеет фиксированную длину.

...