C#
datetime
Binary

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();
    }
}

}