2009-03-20 4 views
1

Я пишу пользовательский сериализатор .NET на C# и хочу читать и записывать объекты Array в XML с помощью XmlReader и XmlWriter. Я хотел бы base64-кодировать массив. Массивы могут быть 1-, 2- или 3-мерными, а элементы - типа bool или numeric.Сериализовать .NET Array для XML в качестве базы 64?

Я полностью в тупике. XmlReader и XmlWriter имеют методы для чтения/записи байт [] массивов в качестве base64, но я не могу понять, как получить из массива в байт [] и обратно.

Массивы могут быть большими, поэтому я бы предпочел решение, которое не требует копирования массива или обработки одного элемента за раз. Небезопасный код и управляемый или собственный C++ - это хорошо. Я мог бы использовать что-то другое, кроме base64, если это безопасно для XML.

Спасибо за любую помощь или подсказки.

ответ

1

У вас будут разные варианты, в зависимости от того, какой тип «Массив» вы используете. Является ли это массивом, списком <> или ArrayList?

Для получения списка <> вы можете использовать CopyTo(), чтобы захватить части вашего списка и поместить их в двоичный массив, который вы могли бы затем написать с помощью XmlWriter. Чтобы прочитать их из XmlReader, вы можете просто использовать InsertRange для де-сериализации данных.

считывающим Пример:

// elsewhere 
List<byte> bytes; 

// in the deserialization 
int bufferSize = 1024; 
byte[] buffer = new byte[bufferSize]; 
int index = 0; 
int numRead = -1; 

while (numRead != 0) // actually read stuff 
{ 
    numRead = reader.ReadContentAsBase64(buffer, bufferSize); 
    if (numRead > 0) 
    { 
     bytes.CopyTo(buffer, index, numRead); 
     index += numRead; 
    } 
} 

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

Чтобы получить другие типы, кроме байтов, в массив байтов, вам нужно будет использовать System.BitConverter. У этого есть два метода, которые сделают вас очень счастливыми: GetBytes, который преобразует любой базовый тип данных в массив байтов и ToXxx, который включает в себя ToInt32 и ToBoolean. Вы будете нести ответственность за это преобразование самостоятельно после того, как прочитаете в базе данных base64 или перед тем, как будете писать.

Вы можете использовать BitConverter для преобразования каждого бит в набор байтов, но вам решать, как разработать алгоритм преобразования ваших массивов в один байт-массив и обратно.

+0

Это System.Array, например byte [] или int [,]. Что вы подразумеваете под «двоичным массивом»? Как мне написать это с помощью XmlWriter? –

+0

См. Обновленный пример. :) –

+0

Ах, 'числовые или булевы типы'. Затем вам нужно будет преобразовать это в какой-то байт-массив, прежде чем вы его запишите. –

0

Если вам нужен один массив, представленный одним элементом XML, содержащим текст Base-64, самым простым способом, вероятно, будет использование BinaryFormatter, чтобы превратить ваши данные (массив любого количества измерений, списка и т. Д.) В байтовый массив, а затем просто base-64 закодировать это и вставить его в файл XML. Я не могу придумать какой-либо другой простой способ превратить произвольные массивы в массивы байтов.

+0

Да, я думаю, это может быть лучшим решением. К сожалению, это требует копирования массива на вывод BinaryFormatter, который я бы предпочел избежать. –

0

Краткое описание того, что я закончил делать: Для сериализации я использую BinaryWriter для записи отдельных элементов в массив байтов, завернутый в MemoryStream. Я разбиваю запись на маленькие куски, поэтому массив MemoryStream остается маленьким. Напишите фрагменты как отдельные элементы XML с содержимым текста в кодировке base64.

Deserialization - это почти наоборот; фрагменты base64 декодируются в массив байтов; массив байтов обертывается потоком памяти и считывается BinaryReader для ввода элементов в массив результатов.

0

Если вы используете XmlSerializer, вы можете указать XmlElementAttribute с свойством DataType, установленным в «base64Binary» в свойстве типа byte []. См. here.