/// <summary>
        /// Возвращает блоб.
        /// </summary>
        /// <param name="id">Идентификатор блоба.</param>
        /// <param name="throwIfNotExists">Выбросить исключение, если блоб не существует?</param>
        /// <returns></returns>
        private Blob GetBlob(int id, bool throwIfNotExists = true)
        {
            if (id < 1)
            {
                throw new ArgumentNullException("id");
            }

            this.Logger.WriteFormatMessage("GetBlob:Начало получения блоба для файла, id: {0}", id);

            //метаданные блоба
            IBlobMetadata metadata = this.BlobMetadataAdapter.GetBlob(id);

            if (throwIfNotExists && metadata == null)
            {
                throw new Exception(string.Format("Не удалось найти блоб с идентификатором {0}", id));
            }

            //метаданные контейнера
            IBlobContainerMetadata containerMetadata = this.BlobMetadataAdapter.GetBlobContainer(metadata.ContainerID);

            if (throwIfNotExists && containerMetadata == null)
            {
                throw new Exception(string.Format("Не удалось найти контейнер блобов с идентификатором {0}", metadata.ContainerID));
            }

            BlobContainer container = new BlobContainer(this, containerMetadata);
            Blob          blob      = new Blob(container, metadata);

            this.Logger.WriteFormatMessage("GetBlob:Окончание получения блоба для файла, id: {0}", id);

            return(blob);
        }
Exemple #2
0
        public Blob(BlobContainer container, IBlobMetadata metadata)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }

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

            this.Container = container;
            this.Metadata  = metadata;
        }
        /// <summary>
        /// Возвращает контейнер блобов для папки.
        /// </summary>
        /// <param name="folderMetadata">Метаданные папки.</param>
        /// <returns></returns>
        private BlobContainer GetBlobContainer(IFolderMetadata folderMetadata)
        {
            if (folderMetadata == null)
            {
                throw new ArgumentNullException("folderMetadata");
            }

            this.Logger.WriteFormatMessage("GetBlobContainer:Начало получения контейнера, folder.Url: {0}", folderMetadata.Url);

            ICollection <IBlobContainerMetadata> blobContainers = this.BlobMetadataAdapter.GetBlobContainers(folderMetadata.ID);

            if (blobContainers == null || blobContainers.Count == 0)
            {
                blobContainers = this.BlobMetadataAdapter.DefaultContainers;
            }

            if (blobContainers == null || blobContainers.Count == 0)
            {
                throw new Exception(string.Format("Не удалось найти ни одного контейнера блобов для папки с именем {0}",
                                                  folderMetadata.Name));
            }

            IBlobContainerMetadata metadata = null;

            if (blobContainers.Count > 1)
            {
                //выбираем рандомный контейнер для записи.
                int index = Math.Abs(Guid.NewGuid().GetHashCode() % blobContainers.Count);
                metadata = blobContainers.ToList()[index];
            }
            else
            {
                metadata = blobContainers.First();
            }

            BlobContainer container = new BlobContainer(this, metadata);

            this.Logger.WriteFormatMessage("GetBlobContainer:Окончание получения контейнера, folder.Url: {0}", folderMetadata.Url);

            return(container);
        }
        private IFileVersionMetadata WriteInternal(IBlobFileMetadata blobFileMetadata, Stream stream, DateTime?remoteTimeCreated = null)
        {
            if (blobFileMetadata == null)
            {
                throw new ArgumentNullException("param");
            }

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

            this.Logger.WriteFormatMessage("WriteFile:Начало записи файла, folderMetadata.Name: {0}, fileName: {1}", blobFileMetadata.FolderMetadata.Name, blobFileMetadata.Name);

            //получение контейнера блобов.
            BlobContainer container = this.GetBlobContainer(blobFileMetadata.FolderMetadata);

            //запись файла в контейнер.
            BlobFileInfo blobFileInfo = container.Write(blobFileMetadata, stream, remoteTimeCreated);

            //установка свойств файла, хранящегося в блобе
            blobFileMetadata.BlobID            = blobFileInfo.BlobID;
            blobFileMetadata.BlobStartPosition = blobFileInfo.BlobStartPosition;
            blobFileMetadata.BlobEndPosition   = blobFileInfo.BlobEndPosition;

            this.Logger.WriteMessage("WriteFile:Начало сохранения метаданных файла");
            IBlobFileVersionMetadata savedVersion = this.BlobMetadataAdapter.SaveFile(blobFileMetadata, blobFileInfo.TimeCreated);

            this.Logger.WriteMessage("WriteFile:Окончание сохранения метаданных файла");

            this.Logger.WriteFormatMessage("WriteFile:Начало записи файла, folderMetadata.Name: {0}, fileName: {1}, fileUniqueID: {2}, fileVersionUniqueID: {3}",
                                           blobFileMetadata.FolderMetadata.Name,
                                           blobFileMetadata.Name,
                                           savedVersion.FileMetadata.UniqueID,
                                           savedVersion.UniqueID);

            return(savedVersion);
        }
        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);
                }
            }
        }