/// <summary> /// Flushes a file's contents. /// </summary> /// <param name="sender">The file to flush.</param> /// <param name="e">This is not used.</param> /// <exception cref="InvalidOperationException"> /// The file has been closed. /// </exception> /// <exception cref="NotSupportedException"> /// Overriding contents not supported. /// </exception> private void Flush(object sender, EventArgs e) { Fat32FileStream file = sender as Fat32FileStream; if (!openedFiles.Contains(file)) { throw new InvalidOperationException("The file has been closed."); } if (file.Entry.FileSize != 0) { throw new NotSupportedException("Overriding contents not supported."); } file.Entry.FileSize = (uint)file.Length; file.Position = 0; byte[] buffer = new byte[boot.BytesPerCluster]; long cluster = -1; while (file.Position != file.Length) { cluster = GetFreeCluster(cluster); if (file.Position == 0) { file.Entry.FirstCluster = (uint)cluster; } Source.Position = FirstSectorOfCluster((uint)cluster) * boot.BytesPerSector; int bytesRead = file.Read(buffer, 0, buffer.Length); Source.Write(buffer, 0, buffer.Length); } }
/// <summary> /// Opens the file specified by the given <paramref name="path"/>. /// </summary> /// <param name="path">The path of the file to open.</param> /// <returns>The opened file stream.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="path"/> is null. /// </exception> /// <exception cref="DirectoryNotFoundException"> /// If the given <paramref name="path"/> contains a directory that doesn't exist /// </exception> /// <exception cref="FileNotFoundException"> /// If the given <paramref name="path"/> is to a file and it doesn't exist /// </exception> public override Stream Open(string path) { if (path == null) { throw new ArgumentNullException(nameof(path)); } if (!Exist(path)) { throw new FileNotFoundException("The file doesn't exist.", nameof(path)); } FileEntry entry = FindEntry(path); long position = Source.Position - 32; byte[] data = GetFileData(entry); Fat32FileStream stream = new Fat32FileStream(data, entry, position); stream.AfterFlush += Flush; stream.AfterClose += Close; openedFiles.Add(stream); return(stream); }
/// <summary> /// Closes a file. /// </summary> /// <param name="sender">The file to flush.</param> /// <param name="e">This is not used.</param> /// <exception cref="InvalidOperationException"> /// The file has already been closed. /// </exception> private void Close(object sender, EventArgs e) { Fat32FileStream stream = sender as Fat32FileStream; if (!openedFiles.Contains(stream)) { throw new InvalidOperationException("The file has already been closed."); } WriteStructure(stream.Offset, stream.Entry); openedFiles.Remove(stream); }