/// <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); }
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); } } }