/// <summary> /// Creates a new <see cref="DataPointScanner"/> instance. /// </summary> /// <param name="dataBlockAllocationTable"><see cref="ArchiveFileAllocationTable"/> for the file to be scanned.</param> /// <param name="historianID">Historian ID to scan for.</param> /// <param name="startTime">Desired start time.</param> /// <param name="endTime">Desired end time.</param> /// <param name="dataReadExceptionHandler">Read exception handler.</param> public DataPointScanner(ArchiveFileAllocationTable dataBlockAllocationTable, int historianID, TimeTag startTime, TimeTag endTime, EventHandler<EventArgs<Exception>> dataReadExceptionHandler) { // Find all data blocks for desired point over given time range m_dataBlocks = dataBlockAllocationTable.FindDataBlocks(historianID, startTime, endTime, false); m_startTime = startTime; m_endTime = endTime; m_historianID = historianID; m_dataReadExceptionHandler = dataReadExceptionHandler; }
/// <summary> /// Closes the <see cref="ArchiveFile"/> if it <see cref="IsOpen"/>. /// </summary> public void Close() { if (IsOpen) { // Abort any asynchronous processing. m_rolloverPreparationThread.Abort(); m_buildHistoricFileListThread.Abort(); // Stop checking allocated data blocks for activity. m_conserveMemoryTimer.Stop(); // Stop the historic and out-of-sequence data queues. m_historicDataQueue.Stop(); m_outOfSequenceDataQueue.Stop(); // Dispose the underlying file stream object. m_fat = null; if (m_fileStream != null) { lock (m_fileStream) { m_fileStream.Dispose(); } m_fileStream = null; } if (m_dataBlocks != null) { lock (m_dataBlocks) { m_dataBlocks.Clear(); } m_dataBlocks = null; } // Stop watching for historic archive files. m_currentLocationFileWatcher.EnableRaisingEvents = false; m_offloadLocationFileWatcher.EnableRaisingEvents = false; // Clear the list of historic archive files. if (m_historicArchiveFiles != null) { lock (m_historicArchiveFiles) { m_historicArchiveFiles.Clear(); } m_historicArchiveFiles = null; } } }
/// <summary> /// Opens the <see cref="ArchiveFile"/> for use. /// </summary> /// <exception cref="InvalidOperationException">One or all of the <see cref="StateFile"/>, <see cref="IntercomFile"/> or <see cref="MetadataFile"/> properties are not set.</exception> public void Open() { if (!IsOpen) { // Check for the existance of dependencies. if (m_stateFile == null || m_intercomFile == null | m_metadataFile == null) throw (new InvalidOperationException("One or more of the dependency files are not specified.")); // Validate file type against its name. m_fileName = m_fileName.ToLower(); if (Path.GetExtension(m_fileName) == StandbyFileExtension) m_fileType = ArchiveFileType.Standby; else if (Regex.IsMatch(m_fileName, string.Format(".+_.+_to_.+\\{0}$", FileExtension))) m_fileType = ArchiveFileType.Historic; else m_fileType = ArchiveFileType.Active; // Get the absolute path for the file name. m_fileName = FilePath.GetAbsolutePath(m_fileName); // Create the directory if it does not exist. if (!Directory.Exists(FilePath.GetDirectoryName(m_fileName))) Directory.CreateDirectory(FilePath.GetDirectoryName(m_fileName)); if (File.Exists(m_fileName)) { // File has been created already, so we just need to read it. m_fileStream = new FileStream(m_fileName, FileMode.Open, m_fileAccessMode, FileShare.ReadWrite); m_fat = new ArchiveFileAllocationTable(this); } else { // File does not exist, so we have to create it and initialize it. m_fileStream = new FileStream(m_fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); m_fat = new ArchiveFileAllocationTable(this); m_fat.Save(); } // Don't proceed further for standby and historic files. if (m_fileType != ArchiveFileType.Active) return; // Start internal process queues. m_historicDataQueue.Start(); m_outOfSequenceDataQueue.Start(); // Open state file if closed. if (!m_stateFile.IsOpen) m_stateFile.Open(); //Open intercom file if closed. if (!m_intercomFile.IsOpen) m_intercomFile.Open(); // Open metadata file if closed. if (!m_metadataFile.IsOpen) m_metadataFile.Open(); // Create data block lookup list. if (m_stateFile.RecordsInMemory > 0) m_dataBlocks = new List<ArchiveDataBlock>(new ArchiveDataBlock[m_stateFile.RecordsInMemory]); else m_dataBlocks = new List<ArchiveDataBlock>(new ArchiveDataBlock[m_stateFile.RecordsOnDisk]); // Start the memory conservation process. if (m_conserveMemory) m_conserveMemoryTimer.Start(); // Ensure that "rollover in progress" is not set. IntercomRecord system = m_intercomFile.Read(1); system.RolloverInProgress = false; m_intercomFile.Write(1, system); // Start preparing the list of historic files. m_buildHistoricFileListThread = new Thread(BuildHistoricFileList); m_buildHistoricFileListThread.Priority = ThreadPriority.Lowest; m_buildHistoricFileListThread.Start(); // Start file watchers to monitor file system changes. m_currentLocationFileWatcher.Filter = HistoricFilesSearchPattern; m_currentLocationFileWatcher.Path = FilePath.GetDirectoryName(m_fileName); m_currentLocationFileWatcher.EnableRaisingEvents = true; if (Directory.Exists(m_fileOffloadLocation)) { m_offloadLocationFileWatcher.Filter = HistoricFilesSearchPattern; m_offloadLocationFileWatcher.Path = m_fileOffloadLocation; m_offloadLocationFileWatcher.EnableRaisingEvents = true; } } }
/// <summary> /// Creates a new instance of the <see cref="TimeSortedDataPointScanner"/>. /// </summary> /// <param name="dataBlockAllocationTable"><see cref="ArchiveFileAllocationTable"/> for the file to be scanned.</param> /// <param name="historianIDs">Historian ID's to scan.</param> /// <param name="startTime">Desired start time.</param> /// <param name="endTime">Desired end time.</param> /// <param name="lastHistorianID">Last read historian ID, or -1 to begin scan at first ID.</param> /// <param name="dataReadExceptionHandler">Read exception handler.</param> public TimeSortedDataPointScanner(ArchiveFileAllocationTable dataBlockAllocationTable, IEnumerable<int> historianIDs, TimeTag startTime, TimeTag endTime, int lastHistorianID, EventHandler<EventArgs<Exception>> dataReadExceptionHandler) { m_dataPointScanners = new List<DataPointScanner>(); // Create data point scanners for each historian ID foreach (int historianID in historianIDs) { // Start scan when last Historian ID is -1, otherwise if last historian ID is encountered, start reading at next point if (lastHistorianID == -1) m_dataPointScanners.Add(new DataPointScanner(dataBlockAllocationTable, historianID, startTime, endTime, dataReadExceptionHandler)); else if (lastHistorianID == historianID) lastHistorianID = -1; } }
internal void CloseStream() { m_fat = null; if (m_fileStream != null) { lock (m_fileStream) { m_fileStream.Flush(); m_fileStream.Close(); m_fileStream.Dispose(); } m_fileStream = null; } }
internal void OpenStream() { if (File.Exists(m_fileName)) { int attempts = 0; while (true) { try { attempts++; m_fileStream = new FileStream(m_fileName, FileMode.Open, m_fileAccessMode, FileShare.ReadWrite); m_fat = new ArchiveFileAllocationTable(this); break; } catch { if (attempts >= 4) throw; Thread.Sleep(500); } } } else { // File does not exist, so we have to create it and initialize it. m_fileStream = new FileStream(m_fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); m_fat = new ArchiveFileAllocationTable(this); m_fat.Save(); // Manually call file monitoring event if file watchers are not enabled if (!m_monitorNewArchiveFiles) FileWatcher_Created(this, new FileSystemEventArgs(WatcherChangeTypes.Created, FilePath.GetAbsolutePath(m_fileName), FilePath.GetFileName(m_fileName))); } }
/// <summary> /// Creates a new instance of the <see cref="FixedTableRegion"/>. /// </summary> /// <param name="parent">Reference to parent <see cref="ArchiveFileAllocationTable"/>.</param> public FixedTableRegion(ArchiveFileAllocationTable parent) { m_parent = parent; }
/// <summary> /// Creates a new instance of the <see cref="VariableTableRegion"/>. /// </summary> /// <param name="parent">Reference to parent <see cref="ArchiveFileAllocationTable"/>.</param> public VariableTableRegion(ArchiveFileAllocationTable parent) { m_parent = parent; }