Почему бинарный файл отличается по размеру от текста?
Я хранил большой набор данных в виде записей TEXT в файле TEXT:
yyyyMMddTHHmmssfff doube1 double2
Однако, когда я читаю это, мне нужно проанализировать каждый DateTime. Это довольно медленно для миллионов записей.
Итак, теперь я пытаюсь сделать это в виде двоичного файла, который я создал путем сериализации своего класса.
Таким образом, мне не нужно анализировать DateTime.
class MyRecord
{
DateTime DT;
double Price1;
double Price2;
}
public byte[] SerializeToByteArray()
{
var bf = new BinaryFormatter();
using (var ms = new MemoryStream())
{
bf.Serialize(ms, this);
return ms.ToArray();
}
}
MyRecord mr = new MyRecord();
outBin = new BinaryWriter(File.Create(binFileName, 2048, FileOptions.None));
for (AllRecords) //Pseudo
{
mr = new MyRecord(); //Pseudo
outBin.Write(mr.SerializeToByteArray());
}
Полученный двоичный файл в среднем в 3 раза больше размера файла TEXT.
Этого следовало ожидать?
РЕДАКТИРОВАТЬ 1
Я изучаю использование Protbuf, чтобы помочь мне:
Я хочу сделать это с помощью USING, чтобы соответствовать моей существующей структуре.
private void DisplayBtn_Click(object sender, EventArgs e)
{
string fileName = dbDirectory + @"\nAD20120101.dat";
FileStream fs = File.OpenRead(fileName);
MyRecord tr;
while (fs.CanRead)
{
tr = Serializer.Deserialize<MyRecord>(fs);
Console.WriteLine("> "+ tr.ToString());
}
}
НО после первой записи tr - полный нулей.
3 ответа
Скорее всего, ваш архив содержит значительную часть информации о типах сериализации для каждой записи.
Вместо этого сделайте всю коллекцию сериализуемой (если она еще не создана) и сериализуйте ее за один раз.
Вы храните не простую двоичную версию вашего DateTime, а представляющий их объект. Это гораздо больше, чем просто хранить дату как текст.
Если вы создаете класс
class MyRecords
{
DateTime[] DT;
double[] Price1;
double[] Price2;
}
И сериализуйте это, это должно быть намного меньше.
Кроме того, я думаю, что DateTime по-прежнему требует много места, поэтому вы можете преобразовать ваш DateTime в временную метку Unix Integer и сохранить ее.
По требованию ОП.
вывод не двоичный файл, это двоичная сериализация экземпляров плюс накладные расходы BinaryFormatter для последующей десериализации, поэтому вы получаете в 3 раза больше файла, чем ожидалось, если вам нужно умное решение для сериализации, вы можете взглянуть на ProtoBuf-net https://code.google.com/p/protobuf-net/
здесь вы можете найти ссылку, объясняющую, как вы можете достичь этого
[ProtoContract]
Public class MyRecord
{ [ProtoMember(1)]
DateTime DT;
[ProtoMember(2)]
double Price1;
[ProtoMember(3)]
double Price2;
}