Example #1
0
        public override void Write(string path, Stream stream = null, FileInformation fileInformation = null, bool match = true)
        {
            if (stream == null)
                throw new ArgumentNullException(nameof(stream));

            int blockSize = fileInformation?.BlockSize ?? DefaultBlockSize;
            path = GetPath(path);
            Directory.GetParent(path).Create();
            using (FileStream fs = new FileStream(path, FileMode.Create))
            {
                stream.CopyTo(fs, blockSize);
            }
        }
Example #2
0
 public abstract void Write(string path, Stream stream = null, FileInformation fileInformation = null, bool match = true);
 public static bool Post(FileInformation data, string id = null)
     => PimixService.Post(data, id);
Example #4
0
 public override void Write(string path, Stream stream = null, FileInformation fileInformation = null, bool match = true)
 {
     var folder = GetNode(GetParent(path), true);
     var name = path.Substring(path.LastIndexOf('/') + 1);
     Client.Upload(stream, name, folder);
 }
Example #5
0
        public FileProperties CompareProperties(FileInformation other, FileProperties propertiesToCompare)
        {
            FileProperties result = FileProperties.None;
            foreach (var p in Properties)
            {
                if (propertiesToCompare.HasFlag(p.Key))
                {
                    if (p.Value.GetValue(other) != null)
                    {
                        if (p.Value.PropertyType.IsAssignableFrom(typeof(List<string>)))
                        {
                            var olist = p.Value.GetValue(other) as List<string>;
                            var tlist = p.Value.GetValue(this) as List<string>;
                            if (!tlist.SequenceEqual(olist))
                            {
                                result |= p.Key;
                            }
                        }
                        else if (!object.Equals(p.Value.GetValue(other), p.Value.GetValue(this)))
                        {
                            result |= p.Key;
                        }
                    }
                }
            }

            return result;
        }
        /// <summary>
        /// Upload data from stream with the optimal method.
        /// </summary>
        /// <param name="path">Path for the destination file.</param>
        /// <param name="stream">Input stream to upload.</param>
        /// <param name="fileInformation">
        /// If specified, contains information about the data to write.
        /// </param>
        /// <param name="match">Whether the fileInformation matches the stream.</param>
        public override void Write(string path, Stream stream = null, FileInformation fileInformation = null, bool match = true)
        {
            fileInformation = fileInformation ?? new FileInformation();
            if (match)
            {
                try
                {
                    UploadStreamRapid(path, stream, fileInformation);
                    return;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Rapid upload failed!\nException:\n{ex}\n");
                }
            }

            if (stream == null)
                throw new ArgumentNullException(nameof(stream));

            if (!stream.CanSeek)
                throw new ArgumentException(
                    "Input stream needs to be seekable!",
                    nameof(stream));

            UploadNormal(path, stream, fileInformation);
        }
        void UploadStreamRapid(string path, Stream input, FileInformation fileInformation)
        {
            fileInformation.AddProperties(input, FileProperties.AllBaiduCloudRapidHashes);

            HttpWebRequest request = ConstructRequest(Config.APIList.UploadFileRapid,
                new Dictionary<string, string>
                {
                    ["remote_path"] = path.TrimStart('/'),
                    ["content_length"] = fileInformation.Size.ToString(),
                    ["content_md5"] = fileInformation.MD5,
                    ["slice_md5"] = fileInformation.SliceMD5,
                    ["content_crc32"] = fileInformation.Adler32
                });

            request.GetRequestStream().Close();

            using (var response = request.GetResponse())
            {
                if (!response.GetDictionary().Contains(new KeyValuePair<string, object>("md5", fileInformation.MD5)))
                    throw new Exception("Response is unexpected!");
            }
        }
        void UploadNormal(string path, Stream input, FileInformation fileInformation)
        {
            fileInformation.AddProperties(input, FileProperties.Size | FileProperties.BlockSize);

            input.Seek(0, SeekOrigin.Begin);

            if (BlockInfo == null || BlockInfo.Count == 0)
            {
                BlockInfo = new List<int> { fileInformation.BlockSize.Value };
            }

            int blockIndex = 0;
            int blockLength = 0;
            byte[] buffer = new byte[BlockInfo.Max()];

            if (BlockInfo[0] >= fileInformation.Size)
            {
                blockLength = input.Read(buffer, 0, BlockInfo[0]);
                bool uploadDirectDone = false;
                while (!uploadDirectDone)
                {
                    try
                    {
                        UploadDirect(path, buffer, 0, blockLength);
                        uploadDirectDone = true;
                    }
                    catch (WebException ex)
                    {
                        Console.WriteLine($"Failed once when uploading file {path} with direct upload method.");
                        Console.WriteLine("Exception:");
                        Console.WriteLine(ex);
                        if (ex.Response != null)
                        {
                            Console.WriteLine("Response:");
                            using (var s = new StreamReader(ex.Response.GetResponseStream()))
                            {
                                Console.WriteLine(s.ReadToEnd());
                            }
                        }
                        Thread.Sleep(TimeSpan.FromSeconds(10));
                    }
                    catch (ObjectDisposedException ex)
                    {
                        Console.WriteLine($"Failed once when uploading file {path} with direct upload method.");
                        Console.WriteLine("Unexpected ObjectDisposedException:");
                        Console.WriteLine(ex);
                        Thread.Sleep(TimeSpan.FromSeconds(10));
                    }
                }
                return;
            }

            List<string> blockIds = new List<string>();

            for (long position = 0; position < fileInformation.Size; position += blockLength)
            {
                blockLength = input.Read(buffer, 0, BlockInfo[blockIndex]);

                bool done = false;
                while (!done)
                {
                    try
                    {
                        blockIds.Add(UploadBlock(buffer, 0, blockLength));
                        done = true;
                    }
                    catch (WebException ex)
                    {
                        Console.WriteLine($"Failed once for file {path}, on block {blockIds.Count}");
                        Console.WriteLine("Exception:");
                        Console.WriteLine(ex);
                        if (ex.Response != null)
                        {
                            Console.WriteLine("Response:");
                            using (var s = new StreamReader(ex.Response.GetResponseStream()))
                            {
                                Console.WriteLine(s.ReadToEnd());
                            }
                        }
                        Thread.Sleep(TimeSpan.FromSeconds(10));
                    }
                    catch (ObjectDisposedException ex)
                    {
                        Console.WriteLine($"Failed once for file {path}, on block {blockIds.Count}");
                        Console.WriteLine("Exception:");
                        Console.WriteLine(ex);
                        Thread.Sleep(TimeSpan.FromSeconds(10));
                    }
                    catch (UploadBlockException ex)
                    {
                        Console.WriteLine($"Failed once for file {path}, on block {blockIds.Count}");
                        Console.WriteLine("Exception:");
                        Console.WriteLine(ex);
                        Thread.Sleep(TimeSpan.FromSeconds(10));
                    }
                }

                if (blockIndex < BlockInfo.Count - 1)
                {
                    // Stay at the last element.
                    blockIndex++;
                }
            }

            bool mergeDone = false;
            while (!mergeDone)
            {
                try
                {
                    MergeBlocks(path, blockIds);
                    mergeDone = true;
                }
                catch (Exception ex)
                {
                    logger.Warn(ex, "Failed when merging");
                    Thread.Sleep(TimeSpan.FromSeconds(10));
                }
            }
        }