public void StoreBytesForExistingStreams(Guid dataIdentifier, byte[] fileData, ICustomMetaData customMetaData, AddFileBehaviour addFileBehaviour) { #region Preconditions and initialization ... if (fileData.LongLength > fileData.Length) { throw new Exception("NFileStorage is (currently) limited to a max length of 32bit (about 4.294.967.296 bytes)"); } // // first check the behaviour conditions // switch (addFileBehaviour) { case AddFileBehaviour.SkipWhenAlreadyExists: if (Exists(dataIdentifier, StreamStateBehaviour.UseExistingStream)) { return; } break; case AddFileBehaviour.ThrowExceptionWhenAlreadyExists: if (Exists(dataIdentifier, StreamStateBehaviour.UseExistingStream)) { throw new Exception(string.Format("File {0} already exists", dataIdentifier)); } break; case AddFileBehaviour.OverrideWhenAlreadyExists: if (Exists(dataIdentifier, StreamStateBehaviour.UseExistingStream)) { DeleteDataIdentifier(dataIdentifier, DeleteFileBehaviour.ThrowExceptionWhenNotExists, StreamStateBehaviour.UseExistingStream); } break; default: throw new NotSupportedException(string.Format("Unsupported behaviour; {0}", addFileBehaviour)); } #endregion bool supportsMetaData = SupportsFeature(FileStorageFeatureEnum.StoreMetaData); long dataOffset = DataStream.Length; int dataLength = fileData.Length; Int64 metaDataOffsetInFileFromBegin; if (supportsMetaData) { if (customMetaData == null) { customMetaData = new EmptyCustomMetaData(); } metaDataOffsetInFileFromBegin = dataOffset + DataFileDataStructSize + dataLength; } else { metaDataOffsetInFileFromBegin = 0; } // create a new struct with offsets 0 for each index in guid var newFileStruct = new DataFileDataStruct { DataIdentification = dataIdentifier, BinaryDataSizeInBytes = dataLength, DataStateEnumID = 0, MetaDataOffsetInFileFromBegin = metaDataOffsetInFileFromBegin, ReservedB = 0 }; #region Store the information in the data file #region Store struct in data file StoreStruct(dataOffset, newFileStruct); #endregion #region Store actual data in data file // // the stream is intentionally left open // var bufferedDataFileStream = new BufferedStream(DataStream); // write the actual data bufferedDataFileStream.Write(fileData, 0, dataLength); // flush, to ensure we don't have bytes in the queue when we close the file bufferedDataFileStream.Flush(); #endregion #region Store meta data in data file if (supportsMetaData) { // // use the DynamiteXML feature to store metadata // var metaDataContainer = new MetaDataContainer(customMetaData, DateTime.UtcNow, dataLength); string metaDataString = DynamiteXmlLogic.Serialize(metaDataContainer); byte[] metaDataBytes = Encoding.UTF8.GetBytes(metaDataString); // // write the length of the bytes of the metadata // var binaryWriter = new BinaryWriter(DataStream); binaryWriter.Write(metaDataBytes.Length); bufferedDataFileStream.Write(metaDataBytes, 0, metaDataBytes.Length); // flush, to ensure we don't have bytes in the queue when we close the file bufferedDataFileStream.Flush(); } #endregion #endregion #region Store the information in the index file // // derive the build index behaviour from the add file behaviour // BuildIndexBehaviour buildIndexBehaviour; switch (addFileBehaviour) { case AddFileBehaviour.ThrowExceptionWhenAlreadyExists: buildIndexBehaviour = BuildIndexBehaviour.ThrowExceptionWhenIndexAlreadyExists; break; case AddFileBehaviour.SkipWhenAlreadyExists: // // this should have been intercepted before, should be impossible // buildIndexBehaviour = BuildIndexBehaviour.ThrowExceptionWhenIndexAlreadyExists; break; case AddFileBehaviour.OverrideWhenAlreadyExists: buildIndexBehaviour = BuildIndexBehaviour.OverrideWhenAlreadyExists; break; default: throw new NotSupportedException(string.Format("Unexpected addFileBehaviour {0}", addFileBehaviour)); } // we update the index file BuildIndex(dataIdentifier, dataOffset, buildIndexBehaviour, StreamStateBehaviour.UseExistingStream); #endregion }
private void StoreStruct(Int64 offsetInFileFromBegin, DataFileDataStruct fileStruct) { // point to the end of the file DataStream.Seek(offsetInFileFromBegin, SeekOrigin.Begin); // write the struct var binaryWriter = new BinaryWriter(DataStream); binaryWriter.Write(fileStruct.DataIdentification.ToByteArray()); binaryWriter.Write(fileStruct.DataStateEnumID); binaryWriter.Write(fileStruct.BinaryDataSizeInBytes); binaryWriter.Write(fileStruct.MetaDataOffsetInFileFromBegin); binaryWriter.Write(fileStruct.ReservedB); }