/// <summary> /// Initializes a new FAT file stream for the specified file. /// </summary> /// <param name="aFile">The file to create a stream to.</param> /// <param name="ignoreFileSize">Whether to ignore the file size or not. True for directories.</param> public FATFileStream(FATFile aFile, bool ignoreFileSize) : base(aFile) { IgnoreFileSize = ignoreFileSize; if (TheFATFile == null) { ExceptionMethods.Throw(new Exception("Could not create FATFileStream. Specified file object was null!")); } GetClusterNums(); }
/// <summary> /// Writes the specified number of the bytes from the buffer starting at offset in the buffer. /// </summary> /// <param name="buffer">The data to write.</param> /// <param name="offset">The offset within the buffer to start writing from.</param> /// <param name="count">The number of bytes to write.</param> public override void Write(byte[] buffer, int offset, int count) { if (count < 0) { ExceptionMethods.Throw(new Exceptions.ArgumentException("FATFileStream.Write: aCount must be > 0")); } else if (offset < 0) { ExceptionMethods.Throw(new Exceptions.ArgumentException("FATFileStream.Write: anOffset must be > 0")); } else if (buffer == null) { ExceptionMethods.Throw(new Exceptions.ArgumentException("FATFileStream.Write: aBuffer must not be null!")); } else if (buffer.Length - offset < count) { ExceptionMethods.Throw(new Exceptions.ArgumentException("FATFileStream.Write: Invalid offset / length values!")); } //BasicConsole.WriteLine("Checks passed."); FATFileSystem mFS = (FATFileSystem)TheFile.TheFileSystem; FATFile mFile = TheFATFile; if (ClusterNums == null) { //BasicConsole.WriteLine("Getting cluster nums..."); GetClusterNums(); if (ClusterNums == null) { //BasicConsole.WriteLine("Failed to get cluster nums."); return; } //BasicConsole.WriteLine("Got cluster nums."); } //BasicConsole.WriteLine("Creating write buffer..."); UInt32 xClusterSize = mFS.BytesPerCluster; byte[] writeBuffer = mFS.NewClusterArray(); //BasicConsole.WriteLine("Writing data..."); while (count > 0) { UInt32 clusterIdx = (UInt32)position / xClusterSize; UInt32 posInCluster = (UInt32)position % xClusterSize; bool newCluster = false; while (clusterIdx >= ClusterNums.Count) { //BasicConsole.WriteLine("Expanding clusters..."); UInt32 lastClusterNum = ClusterNums[ClusterNums.Count - 1]; UInt32 nextClusterNum = mFS.GetNextFreeCluster(lastClusterNum); //Clear cluster mFS.WriteCluster(nextClusterNum, null); //Set last FAT entry to point to next cluster mFS.SetFATEntryAndSave(lastClusterNum, nextClusterNum); //Set next cluster as EOF mFS.SetFATEntryAndSave(nextClusterNum, FATFileSystem.GetFATEntryEOFValue(mFS.FATType)); //Add next cluster num to our list ClusterNums.Add(nextClusterNum); newCluster = true; } if ((posInCluster != 0 || count < xClusterSize) && !newCluster) { //BasicConsole.WriteLine("Reading existing data..."); mFS.ReadClusters(ClusterNums[(int)clusterIdx], 1, writeBuffer); //BasicConsole.WriteLine("Read existing data."); } //BasicConsole.WriteLine("Calculating write size..."); int writeSize = count < (xClusterSize - posInCluster) ? count : (int)(xClusterSize - posInCluster); //BasicConsole.WriteLine("Calculated write size. Copying data to write..."); Array.Copy(buffer, offset, writeBuffer, (int)posInCluster, writeSize); //BasicConsole.WriteLine("Data copied. Writing data to disk..."); mFS.WriteCluster(ClusterNums[(int)clusterIdx], writeBuffer); //BasicConsole.WriteLine("Written data."); count -= writeSize; offset += writeSize; position += (uint)writeSize; } mFS.CleanDiskCaches(); //BasicConsole.WriteLine("Write completed."); if (!IgnoreFileSize) { if (position > mFile.Size) { //Update file info mFile.Size = position; //Update directory entry mFile.Parent.WriteListings(); } } }