//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System; using System.IO; using System.Threading; using TouchSocket.Core; namespace TouchSocket.Rpc.TouchRpc { /// /// 文件流 /// internal class TouchRpcFileStream : DisposableObject { private static int m_saveInterval = 1000; private TouchRpcFileInfo m_fileInfo; private FileStorageWriter m_fileWriter; private TimeSpan m_lastTime; private string m_path; private bool m_resume; /// /// 进度保存时间,默认1000毫秒。 /// public static int SaveInterval { get => m_saveInterval; set { if (value < 0) { value = 0; } m_saveInterval = value; } } public FileStorageWriter FileWriter => m_fileWriter; public static TouchRpcFileStream Create(string path, ref TouchRpcFileInfo fileInfo, bool resume) { TouchRpcFileStream stream = new TouchRpcFileStream(); stream.m_fileWriter = FilePool.GetWriter(path + ".rrqm"); stream.m_fileWriter.Position = fileInfo.Position; stream.m_fileInfo = fileInfo; stream.m_path = path; stream.m_resume = resume; return stream; } public void FinishStream() { if (m_fileWriter.Position != m_fileInfo.Length) { throw new Exception("已完成传输,但是文件长度不对。"); } if (File.Exists(m_path)) { File.Delete(m_path); } m_fileWriter.SafeDispose(); string rrqmPath = m_path + ".rrqm"; string tempPath = m_path + ".temp"; if (!SpinWait.SpinUntil(() => { File.Move(rrqmPath, m_path); if (File.Exists(tempPath)) { File.Delete(tempPath); } if (File.Exists(m_path)) { return true; } return false; }, 5000)) { throw new IOException("已完成传输,但是在保存路径并未检测到文件存在。"); } } public void Write(byte[] buffer, int offset, int length) { m_fileWriter.Write(buffer, offset, length); SaveProgress(); } protected override void Dispose(bool disposing) { m_fileWriter.SafeDispose(); base.Dispose(disposing); } /// /// 保存进度 /// private void SaveProgress() { if (m_resume) { if (DateTime.Now.TimeOfDay - m_lastTime > TimeSpan.FromMilliseconds(m_saveInterval)) { try { File.WriteAllText(m_path + ".temp", m_fileInfo.ToJson()); m_lastTime = DateTime.Now.TimeOfDay; } catch { } } } } } }