Как эффективно преобразовать String, integer, double, datetime в двоичный файл и наоборот? - PullRequest
0 голосов
/ 19 февраля 2011

Я довольно новичок в C # (я использую .NET 4.0), поэтому, пожалуйста, потерпите меня. Мне нужно сохранить некоторые свойства объекта (их свойства int, double, String, boolean, datetime) в файл. Но я хочу зашифровать файлы, используя свое собственное шифрование, поэтому я не могу использовать FileStream для преобразования в двоичный файл. Также я не хочу использовать сериализацию объектов из-за проблем с производительностью. Идея проста: сначала мне нужно каким-то образом преобразовать объекты (их свойства) в двоичный (массив), затем зашифровать (своего рода xor) массив и добавить его в конец файла. При чтении сначала расшифруйте массив, а затем каким-то образом преобразуйте двоичный массив обратно в свойства объекта (из которого я буду генерировать объекты).

Я знаю (примерно =)) как конвертировать эти вещи вручную, и я мог бы закодировать это, но это было бы бесполезно (слишком медленно). Я думаю, что лучшим способом было бы просто получить представление свойств в памяти и сохранить его. Но я не знаю, как это сделать с помощью C # (может быть, с помощью указателей?). Также я думал об использовании MemoryStream, но опять же думаю, что это будет неэффективно. Я имею в виду конвертер классов, но он не поддерживает toByte (datetime) (документация говорит, что он всегда выдает исключение).

Для обратного преобразования я думаю, что единственным вариантом является класс Converter.

Примечание: Я знаю структуру объектов, и они не изменятся, также известна максимальная длина строки.

Спасибо за все ваши идеи и время.

РЕДАКТИРОВАТЬ: я буду хранить только части объектов, в некоторых случаях также части различных объектов (пару свойств от одного типа объекта и пару от другого), поэтому я думаю, что сериализация не вариант для меня.

Ответы [ 3 ]

4 голосов
/ 19 февраля 2011

Вы можете сериализовать их с помощью BinaryFormatter и, прежде чем записать их в FileStream, зашифровать их.Это будет писать и читать объект (я использую DateTime в качестве примера)

using (FileStream sw = File.Create("D:\\Test.bin"))
{
     BinaryFormatter bf = new BinaryFormatter();
     bf.Serialize(sw, DateTime.Now);
}

using (FileStream sw = File.Open("D:\\Test.bin", FileMode.Open))
{
     BinaryFormatter bf = new BinaryFormatter();
     DateTime dt2 = (DateTime)bf.Deserialize(sw);
}

Если вы просто хотите «двоичное» содержимое базового типа, вы можете использовать:

Для DateTime вы сохраняете свойство Tick (и, если хотите, свойство Kind).Для строки вы используете Encoding.UTF8.GetBytes.

1 голос
/ 19 февраля 2011

Есть много разных способов сделать это. Возможно, самое простое и производительность должна быть адекватной: записать каждую запись в MemoryStream, получить результирующий массив байтов, выполнить шифрование этого массива, а затем записать массив в файл, используя FileStream и BinaryWriter.

FileStream fs = new FileStream(...);
BinaryWriter fileWriter = new BinaryWriter(fs);

// Allocate byte array big enough to hold the longest record
byte[] RecordBuffer = new byte[MaxRecordSize];
int recordLength;  // to get the number of bytes in a record.

// for each record
using (var ms = new MemoryStream())
{
    using (var memWriter = new BinaryWriter(ms, Encoding.UTF8))
    {
        // write things to the memory stream
        memWriter.Write(myStringValue);
        memWriter.Write(myLongValue);
        // ... etc.
        // Now get the number of bytes written
        memWriter.Flush();
        recordLength = memWriter.Position;
    }
}

// The record is now serialized in RecordBuffer, from 0 to recordLength-1
// Do your encryption.
// Then write a count of bytes, and the buffer:
fileWriter.Write(recordLength);
fileWriter.Write(RecordBuffer, 0, recordLength);

Прочитать это обратно довольно просто. Вы устанавливаете BinaryReader для файла, вызываете ReadInt32, чтобы получить длину записи, вызываете Read(RecordBuffer, 0, length), чтобы получить байты записи, делаете расшифровку, а затем используете MemoryStream для десериализации.

0 голосов
/ 19 февраля 2011

Я публикую это как ответ, так как я слишком зеленый, чтобы писать комментарии.

Начните с сериализации целых классов, как сказали Йенс и Ксанатос.Скорее всего это будет хорошо.Лучший способ выяснить это - попробовать.

Если вам действительно нужно уменьшить размер файлов, создайте новые классы, содержащие только те элементы, которые необходимо сериализовать.Когда вы собираетесь записать файл, вы можете преобразовать ваши большие объекты в меньший формат и сериализовать его, а затем, когда вы загрузите файл, вы сможете снова инициализировать полные объекты из меньших.

...