/// <summary> /// Opens the historian archive file. /// </summary> /// <param name="fileName">File name of historian archive to open.</param> public void Open(string fileName) { m_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 8192, FileOptions.SequentialScan); int footerPosition = (int)m_fileStream.Length - 32; m_fileStream.Position = footerPosition; using (BinaryReader reader = new BinaryReader(m_fileStream, Encoding.Default, true)) { m_startTime = TimeTag.Convert(reader.ReadDouble()); m_endTime = TimeTag.Convert(reader.ReadDouble()); m_pointsReceived = reader.ReadInt32(); m_pointsArchived = reader.ReadInt32(); m_dataBlockSize = reader.ReadInt32(); m_dataBlockCount = reader.ReadInt32(); int fatPosition = footerPosition - 10 - 12 * m_dataBlockCount; m_fileStream.Position = fatPosition; m_dataBlocks = new List <DataBlock>(m_dataBlockCount); // Scan through header bytes reader.ReadBytes(10); DataBlock block = default(DataBlock); for (int x = 1; x <= m_dataBlockCount; x++) { block.BlockID = reader.ReadInt32(); block.Timestamp = TimeTag.Convert(reader.ReadDouble()); m_dataBlocks.Add(block); } m_fileStream.Position = 0; m_buffer = new byte[m_dataBlockSize * 1024]; } }
public unsafe void Read(Action <Points> callback) { using (MemoryStream FS = new MemoryStream(System.IO.File.ReadAllBytes(File))) //using (System.IO.FileStream FS = new System.IO.FileStream(File, System.IO.FileMode.Open, System.IO.FileAccess.Read,System.IO.FileShare.Read,8192,System.IO.FileOptions.SequentialScan)) { int FooterPOS = (int)FS.Length - 32; FS.Position = FooterPOS; BinaryReader RD = new BinaryReader(FS); DateTime StartTime = TimeTag.Convert(RD.ReadDouble()); DateTime EndTime = TimeTag.Convert(RD.ReadDouble()); int PointsReceived = RD.ReadInt32(); int PointsArchived = RD.ReadInt32(); int DataBlockSize = RD.ReadInt32(); int DataBlockCount = RD.ReadInt32(); int FATPos = FooterPOS - 10 - 12 * DataBlockCount; FS.Position = FATPos; List <Blocks> Blocks = new List <Blocks>(DataBlockCount); byte[] Header = RD.ReadBytes(10); Blocks B = default(Blocks); for (int x = 1; x <= DataBlockCount; x++) { B.BlockID = RD.ReadInt32(); B.Time = TimeTag.Convert(RD.ReadDouble()); Blocks.Add(B); } FS.Position = 0; Points P = default(Points); int NextPos = DataBlockSize * 1024; byte[] Buffer = new byte[DataBlockSize * 1024]; fixed(byte *lp = Buffer) { foreach (Blocks BK in Blocks) { FS.Read(Buffer, 0, DataBlockSize * 1024); int pos = 0; while (pos < DataBlockSize * 1024 - 9) { int I = *(int *)(lp + pos); short S = *(short *)(lp + pos + 4); float V = *(float *)(lp + pos + 6); pos += 10; long TimeDiff = I * 1000L + (S >> 5); if (TimeDiff != 0) { P.Time = TimeTag.Convert(TimeDiff); P.Value = V; P.PointID = BK.BlockID; callback(P); } } //FS.Position = NextPos; NextPos += DataBlockSize * 1024; } return; } } }