示例#1
0
        public void ReadToFolder(PackageDataStream readStream, string rootDirectory)
        {
            if (readStream == null)
            {
                throw new ArgumentNullException(nameof(readStream));
            }

            if (rootDirectory == null)
            {
                throw new ArgumentNullException(nameof(rootDirectory));
            }

            rootDirectory = RemoveTrailingSlashIfPresent(rootDirectory);

            // ensure directory exists
            var rootDirectoryInfo = new DirectoryInfo(rootDirectory);

            rootDirectoryInfo.Create();

            var version = serializer.Deserialize <ClientVersion>(readStream);

            compatibilityChecker.ThrowIfNotCompatibleWith("Package", version);

            var foldersStack = new Stack <string>();

            while (true)
            {
                // read entry
                var entry = serializer.Deserialize <PackageEntry>(readStream);

                if (entry == null)
                {
                    throw new InvalidOperationException("Cannot deserialize package entry.");
                }

                // final entry
                if (entry.Name == null)
                {
                    // really end of stream?
                    if (readStream.Position != readStream.Length)
                    {
                        throw new InvalidOperationException("Unexpected stream end.");
                    }

                    // final entry should pop to root directory
                    if (entry.PopDirectories != foldersStack.Count)
                    {
                        throw new InvalidOperationException("Invalid number of directory pops on final entry.");
                    }

                    return;
                }

                EntriesCount++;

                // get to correct directory
                for (int i = 0; i < entry.PopDirectories; i++)
                {
                    if (foldersStack.Count == 0)
                    {
                        throw new InvalidOperationException("Invalid number of directory pops.");
                    }
                    foldersStack.Pop();
                }

                var currentFolder = foldersStack.Count > 0 ? foldersStack.Peek() : rootDirectory;
                var path          = Path.Combine(currentFolder, entry.Name);

                // is it directory?
                if (entry.Attributes.HasFlag(FileAttributes.Directory))
                {
                    if (entry.FileSize != null)
                    {
                        throw new InvalidOperationException("File size is expected to be null for directory entry.");
                    }

                    var dir = new DirectoryInfo(path);
                    if (dir.Exists)
                    {
                        throw new InvalidOperationException($"Folder \"{dir.Name}\" already exists. Full path: {dir.FullName}");
                    }
                    dir.Create();
                    ApplyAttributes(dir, entry);
                    foldersStack.Push(dir.FullName);
                    continue;
                }

                // or is it file?
                if (entry.FileSize == null)
                {
                    throw new InvalidOperationException("File size is null.");
                }
                using (var fileStream = new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, DefaultBufferSize))
                {
                    fileStream.SetLength(entry.FileSize.Value);
                    if (entry.FileSize.Value > 0)
                    {
                        // write content
                        readStream.CopyStream(fileStream, DefaultBufferSize, entry.FileSize.Value);
                    }
                }
                var fileInfo = new FileInfo(path);
                ApplyAttributes(fileInfo, entry);
            }
        }