Beispiel #1
0
        /// <summary>
        /// Записывает содержимое файла в блоб.
        /// </summary>
        /// <param name="fileMetadata">Матаданные файла.</param>
        /// <param name="stream">Содержимое файла.</param>
        /// <param name="remoteTimeCreated">Время создания версии с удаленного узла.</param>
        /// <returns></returns>
        internal BlobFileInfo Write(IBlobFileMetadata fileMetadata, Stream stream, DateTime?remoteTimeCreated = null)
        {
            if (fileMetadata == null)
            {
                throw new ArgumentNullException("fileMetadata");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            this.Container.DataAdapter.Logger.WriteFormatMessage("Blob.Write:Начало записи содержимого в блоб, file.UniqueID: {0}", fileMetadata.UniqueID);

            BlobFileInfo blobFileInfo = new BlobFileInfo();

            blobFileInfo.BlobID = this.ID;
            bool closeBlob = false;

            DateTime timeCreated;

            if (remoteTimeCreated.HasValue)
            {
                timeCreated = remoteTimeCreated.Value;
            }
            else
            {
                //начиная с 4ой версии хранится время в UTC
                timeCreated = DateTime.Now.ToUniversalTime();
            }

            using (FileStream fs = this.File.Open(FileMode.Append, FileAccess.Write, FileShare.Read))
            {
                BlobStreamAdapter streamAdapter = new BlobStreamAdapter(fs);
                blobFileInfo.BlobStartPosition = fs.Length;
                streamAdapter.Write(fileMetadata, stream, timeCreated);
                blobFileInfo.BlobEndPosition = fs.Length;
                blobFileInfo.TimeCreated     = timeCreated;

                closeBlob = fs.Length > this.Container.DataAdapter.MaxBlobSize;
            }

            if (closeBlob)
            {
                this.Metadata.Closed = true;
                this.Container.DataAdapter.BlobMetadataAdapter.SaveBlob(this.Metadata);
            }

            this.Container.DataAdapter.Logger.WriteFormatMessage("Blob.Write:Окончание записи содержимого в блоб, file.UniqueID: {0}. Блоб был закрыт после записи файла: {1}",
                                                                 fileMetadata.UniqueID,
                                                                 closeBlob);

            return(blobFileInfo);
        }
Beispiel #2
0
        /// <summary>
        /// Считывает поток данных файла из блоба.
        /// </summary>
        /// <param name="fileMetadata">Метаданные файла.</param>
        /// <returns></returns>
        internal Stream ReadStream(IBlobFileMetadata fileMetadata)
        {
            if (fileMetadata == null)
            {
                throw new ArgumentNullException("fileMetadata");
            }

            //поток закрывает объект, предоставляющий средства потоковой передачи
            FileStream        fs            = this.File.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            BlobStreamAdapter streamAdapter = new BlobStreamAdapter(fs);
            PartitionStream   stream        = streamAdapter.ReadStream(fileMetadata);

            return(stream);
        }
Beispiel #3
0
        /// <summary>
        /// Возвращает содержимое файла.
        /// </summary>
        /// <param name="fileMetadata">Метаданные файла.</param>
        /// <returns></returns>
        internal byte[] Read(IBlobFileMetadata fileMetadata)
        {
            if (fileMetadata == null)
            {
                throw new ArgumentNullException("fileMetadata");
            }

            if (fileMetadata.BlobStartPosition < 0)
            {
                throw new ArgumentNullException("fileMetadata.BlobStartPosition");
            }

            if (fileMetadata.BlobEndPosition < 1)
            {
                throw new ArgumentNullException("fileMetadata.BlobEndPosition");
            }

            this.Container.DataAdapter.Logger.WriteFormatMessage("Blob.Read:Начало чтения содержимого из блоба, blobStartPosition: {0}, blobEndPosition: {1}", fileMetadata.BlobStartPosition, fileMetadata.BlobEndPosition);

            //для операции чтения блоб должен всегда существовать
            if (!this.File.Exists)
            {
                throw new Exception(string.Format("Не удалось найти блоб по пути {0}",
                                                  this.File.FullName));
            }

            byte[] content = null;
            using (FileStream fs = this.File.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                BlobStreamAdapter streamAdapter = new BlobStreamAdapter(fs);
                content = streamAdapter.Read(fileMetadata);
            }
            this.Container.DataAdapter.Logger.WriteFormatMessage("Blob.Read:Окончание чтения содержимого из блоба, blobStartPosition: {0}, blobEndPosition: {1}", fileMetadata.BlobStartPosition, fileMetadata.BlobEndPosition);

            return(content);
        }
        public void Restore()
        {
            //проверяем поочередно каждый блоб каждого контейнера
            foreach (IBlobContainerMetadata containerMetadata in this.Containers)
            {
                try
                {
                    //получаем все блобы контейнера
                    ICollection <IBlobMetadata> blobs = this.DataAdapter.BlobMetadataAdapter.GetBlobs(containerMetadata.ID);
                    if (blobs == null || blobs.Count == 0)
                    {
                        continue;
                    }

                    BlobContainer container = new BlobContainer(this.DataAdapter, containerMetadata);
                    //Алгоритм восстановления метаданных
                    //1 - получаем все блобы всех контейнеров
                    //нужно посмотреть все блобы и закрытие и открытые.
                    //потому что после запуска процедуры восстановления метаданных может пойти запись в не до конца восстановленный блоб
                    //и он станет закрытым, но восстановление не завершилось.

                    /*foreach (IBlobMetadata blobMetadata in blobs)
                     * {
                     *  object tmp = blobMetadata.Closed;
                     * }*/

                    //2 - для каждого блоба смотрим его позицию, до которой мы проверили целостность этого блоба
                    foreach (IBlobMetadata blobMetadata in blobs)
                    {
                        Blob blob = new Blob(container, blobMetadata);
                        try
                        {
                            long blobIntegrityPosition = blobMetadata.IntegrityPosition;
                            long filelenth             = blob.File.Length;

                            //целостность метаданных файлов блоба до конца проверена
                            while (blobIntegrityPosition < filelenth)
                            {
                                using (FileStream fs = blob.File.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                                {
                                    BlobStreamAdapter streamAdapter = new BlobStreamAdapter(fs);
                                    if (blobIntegrityPosition == 0)
                                    {
                                        //блоб может начинаться с системного заголовка.
                                        //а может с файла
                                        //тогда нужно сместить начальную позицию на этот системный заголовок
                                        //читаем позицию первого файла
                                        long firstFilePosition = streamAdapter.GetFirstFilePosition();
                                        blob.UpdateIntegrityPosition(firstFilePosition);
                                        blobIntegrityPosition = blobMetadata.IntegrityPosition;
                                    }


                                    //заголовок из файла
                                    object          fileHeaderObj  = streamAdapter.GetFileHeader(blobIntegrityPosition);
                                    IFileHeader     fileHeader     = (IFileHeader)fileHeaderObj;
                                    IBlobFileHeader blobFileHeader = (IBlobFileHeader)fileHeaderObj;

                                    long fileStartPosition = blobMetadata.IntegrityPosition;
                                    if (fileStartPosition != blobFileHeader.ContentAbsoluteStartPosition)
                                    {
                                        throw new Exception(string.Format("Позиция целостности блоба не соответствует позиции начала файла"));
                                    }

                                    long fileEndPosition = fileStartPosition
                                                           + BlobStreamAdapter.SystemHeaderLength
                                                           + blobFileHeader.HeaderLength
                                                           + blobFileHeader.ContentLength;

                                    //восстанавливаем метаданные, если их нет
                                    this.EnsureMetadata(blobMetadata, fileHeader, fileStartPosition, fileEndPosition);

                                    //увеличиваем позицию целостности метаданных блоба
                                    blob.UpdateIntegrityPosition(fileEndPosition);
                                    blobIntegrityPosition = blobMetadata.IntegrityPosition;
                                }
                            }
                        }
                        catch (Exception blobEx)
                        {
                            this.DataAdapter.Logger.WriteFormatMessage("Ошибка при восстановлении метаданных блоба с идентификатором {0} для контейнера {1}. Текст ошибки: {2}",
                                                                       blob.ID,
                                                                       containerMetadata.Path,
                                                                       blobEx);
                        }
                    }
                }
                catch (Exception containerEx)
                {
                    this.DataAdapter.Logger.WriteFormatMessage("Ошибка при восстановлении метаданных контейнера {0}. Текст ошибки: {1}",
                                                               containerMetadata.Path,
                                                               containerEx);
                }
            }
        }