Edited at

C#でbinaryでDateTimeを読み書き


目的

時系列でデータをファイルに記録していく際に、記録時刻もつけて保存することがあります。これを人間がわかりやすいようにText形式で書き込んだりすると、ファイルサイズが増えるだけではなくて、読み込みの際の手間が増えてしまいます。面倒くさがりの私は、これをなるだけ楽にできるようにしました。


 方法

FileStream, BinaryWriterを使うところは他の方が書かれているものと同じです。


書き込み

DateTime は基準時刻(ここではUNIXのEPOCH TIME 1970/1/1 00:00:00)からの時間をmillisecond単位を得て、この時間をdoublea型の変数として、書き込みます。


読み込み

FileStreamで一度にファイルを読み込みます。もしフィアルサイズが大きくて、一度に読み込めない場合は、 FileStream.Read でoffset, countを指定することで分割して読み込むことができます。

Binary dataは byte[]形式で 読み込み、そのデータをBitConverterを使って、元の変数に戻します。

`Write code'

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.IO;

static void Main(string[] args)

{

FileStream fs = new FileStream("test.bin", FileMode.Create);


BinaryWriter bw = new BinaryWriter(fs);


DateTime refTime = new DateTime(1970, 1, 1, 0, 0, 0);


int s;


unsafe


{

s = sizeof(DateTime);

Console.WriteLine(s.ToString());

}

        for ( UInt64 i = 0; i < 10; i++)

{
DateTime Now = DateTime.Now;
TimeSpan dt = Now - refTime;
double timeVar = dt.TotalMilliseconds;
bw.Write(timeVar);
bw.Write(i);

Console.WriteLine(timeVar.ToString() + " " + i.ToString());
System.Threading.Thread.Sleep(950);

}

Console.ReadLine();

fs.Close();
}
}

}

'Read Code'

using System;

using System.IO;

namespace readBin

{

class Program

{

static void Main(string[] args)

{

        Uri startupPath, targetPath;

FileStream fs = new FileStream("../../../../writeBin/bin/Debug/test.bin", FileMode.Open, FileAccess.Read);

byte[] buf = new byte[1000]; // define buffer
fs.Read(buf); // read binary file
fs.Read()
double timeVar;
DateTime Now;
DateTime refTime = new DateTime(1970, 1, 1, 0, 0, 0); // Unix EPoch time

UInt64 count;

for (int i = 0; i < 10; i++)
{
timeVar = BitConverter.ToDouble(buf, i * 16);
count = BitConverter.ToUInt64(buf, i * 16 + 8);
Now = refTime.AddMilliseconds(timeVar);
double micro = timeVar % 1000;
Console.WriteLine(Now.ToShortDateString() + " " + Now.ToLongTimeString() + ":" + micro.ToString() +" " + count.ToString());
}

Console.ReadLine();
}
}

}