예제 #1
0
        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
        }
예제 #2
0
 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);
 }