//============================================================== // Copyright (C) 2019 Inc. All rights reserved. // //============================================================== // Create by 种道洋 at 2019/12/27 18:45:02. // Version 1.0 // 种道洋 //============================================================== using System; using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace Cdy.Tag { /// /// /// public class LocalFileSeriser : DataFileSeriserbase { #region ... Variables ... private System.IO.Stream mStream; #endregion ...Variables... #region ... Events ... #endregion ...Events... #region ... Constructor... #endregion ...Constructor... #region ... Properties ... /// /// /// public override string Name => "LocalFile"; #endregion ...Properties... #region ... Methods ... #endregion ...Methods... #region ... Interfaces ... #endregion ...Interfaces... /// /// /// public override long CurrentPostion => mStream.Position; /// /// /// public override long Length => mStream.Length; /// /// /// /// public override bool CreatOrOpenFile(string filename) { this.FileName = filename; if(System.IO.File.Exists(filename)) { mStream = System.IO.File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); return false; } else { string dir = System.IO.Path.GetDirectoryName(filename); if (!string.IsNullOrEmpty(dir) && !System.IO.Directory.Exists(dir)) { System.IO.Directory.CreateDirectory(dir); } mStream = System.IO.File.Create(filename, 1024,FileOptions.WriteThrough); return true; } } /// /// /// public override DataFileSeriserbase Flush() { try { if (mStream != null && mStream.CanWrite) mStream.Flush(); } catch { } return this; } /// /// /// public override DataFileSeriserbase Close() { try { if (mStream != null) { mStream.Close(); } } catch { } return this; } /// /// /// /// /// public override bool CheckExist(string filename) { return System.IO.File.Exists(filename); } /// /// /// /// /// /// public override MarshalMemoryBlock Read(long start, int len) { var vtmp = len / 1024 * 100; vtmp = len % (1024 * 100) > 0 ? vtmp + 1 : vtmp; MarshalMemoryBlock re = new MarshalMemoryBlock(len, 1024 * 100); mStream.Position = start; byte[] bval = new byte[len]; mStream.Read(bval, 0, len); re.WriteBytesDirect(0, bval); //mStream.Write(re.StartMemory, 0, len); return re; } /// /// /// /// /// /// public override DataFileSeriserbase Write(byte[] source, long start) { mStream.Position = start; mStream.Write(source, 0, source.Length); return this; } /// /// /// /// /// /// /// public override DataFileSeriserbase Write(byte[] source, long start, int offset, int len) { mStream.Position = start; mStream.Write(source, offset, len); return this; } /// /// /// /// /// /// public override DataFileSeriserbase Append(byte[] source, int offset, int len) { //Stopwatch sw = new Stopwatch(); //sw.Start(); mStream.Position = mStream.Length; mStream.Write(source, offset, len); //LoggerService.Service.Info("LocalFileSeriser", "写入文件耗时:" + sw.ElapsedMilliseconds + " 文件大小:" + len / 1024.0 / 1024.0); return this; } /// /// /// /// public override DataFileSeriserbase AppendZore(int len) { mStream.Position = mStream.Length; int size = 1024 * 128; //byte[] bvals = new byte[size]; var bvals = ArrayPool.Shared.Rent(size); try { for (int i = 0; i < (len / size); i++) { mStream.Write(bvals, 0, bvals.Length); } int csize = len % size; if (csize > 0) { mStream.Write(bvals, 0, csize); } } catch { } ArrayPool.Shared.Return(bvals); return this; } /// /// /// /// /// public override long ReadLong(long start) { mStream.Position = start; //byte[] re = new byte[8]; var re = ArrayPool.Shared.Rent(8); try { mStream.Read(re, 0, re.Length); return BitConverter.ToInt64(re, 0); } finally { ArrayPool.Shared.Return(re); } } /// /// /// /// /// public override int ReadInt(long start) { mStream.Position = start; //byte[] re = new byte[4]; var re = ArrayPool.Shared.Rent(4); try { mStream.Read(re, 0, re.Length); return BitConverter.ToInt32(re, 0); } finally { ArrayPool.Shared.Return(re); } } /// /// /// /// /// public override float ReadFloat(long start) { mStream.Position = start; // byte[] re = new byte[4]; var re = ArrayPool.Shared.Rent(4); try { mStream.Read(re, 0, re.Length); return MemoryHelper.ReadFloat(re); } finally { ArrayPool.Shared.Return(re); } } /// /// /// /// /// public override double ReadDouble(long start) { mStream.Position = start; // byte[] re = new byte[8]; var re = ArrayPool.Shared.Rent(8); try { mStream.Read(re, 0, re.Length); return MemoryHelper.ReadDouble(re); } finally { ArrayPool.Shared.Return(re); } } /// /// /// /// /// /// public override byte[] ReadBytes(long start, int len) { mStream.Position = start; byte[] re = new byte[len]; mStream.Read(re, 0, re.Length); return re; } public override DateTime ReadDateTime(long start) { mStream.Position = start; // byte[] re = new byte[8]; var re = ArrayPool.Shared.Rent(8); try { mStream.Read(re, 0, re.Length); return MemoryHelper.ReadDateTime(re); } finally { ArrayPool.Shared.Return(re); } // return DateTime.FromBinary(BitConverter.ToInt64(re, 0)); } /// /// /// /// /// public override short ReadShort(long start) { mStream.Position = start; byte[] re = new byte[2]; mStream.Read(re, 0, re.Length); return BitConverter.ToInt16(re, 0); } /// /// /// /// /// public override byte ReadByte(long start) { mStream.Position = start; return (byte)mStream.ReadByte(); } /// /// /// /// /// public override DataFileSeriserbase Write(DateTime value, long start) { mStream.Position = start; mStream.Write(MemoryHelper.GetBytes(value), 0, 8); return this; } /// /// /// /// /// public override DataFileSeriserbase Write(long value, long start) { mStream.Position = start; var re = BitConverter.GetBytes(value); mStream.Write(re, 0, re.Length); return this; } /// /// /// /// /// public override DataFileSeriserbase Write(int value, long start) { mStream.Position = start; var re = BitConverter.GetBytes(value); mStream.Write(re, 0, re.Length); return this; } /// /// /// /// /// public override DataFileSeriserbase Write(short value, long start) { mStream.Position = start; var re = BitConverter.GetBytes(value); mStream.Write(re, 0, re.Length); return this; } /// /// /// /// /// public override DataFileSeriserbase Write(byte value, long start) { mStream.Position = start; mStream.WriteByte(value); return this; } /// /// /// /// public override DataFileSeriserbase New() { return new LocalFileSeriser(); } /// /// /// /// public override Stream GetStream() { return mStream; } /// /// /// public override void Dispose() { Close(); if(mStream!=null) { mStream = null; } } public override DataFileSeriserbase CloseAndReOpen() { long pos = mStream.Position; Close(); OpenFile(FileName); mStream.Position = pos; return this; } /// /// /// /// /// public override bool OpenFile(string filename) { if (System.IO.File.Exists(filename)) { this.FileName = filename; mStream = System.IO.File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); return true; } return false; } /// /// /// /// /// public override bool OpenForReadOnly(string filename) { if (System.IO.File.Exists(filename)) { this.FileName = filename; mStream = System.IO.File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); return true; } return false; } /// /// /// public override DataFileSeriserbase GoToEnd() { mStream.Position = mStream.Length; return this; } /// /// /// /// /// public override DataFileSeriserbase Write(List source, long start, int offset, int len) { List> copyIndex = new List>(); int sstart = offset; int count = 0; int precount = 0; int copyed = 0; for (int i = 0; i < source.Count; i++) { precount = count; count = source[i].Length + count; if (count > sstart) { var ltmp = count - sstart; if (ltmp > (len - copyed)) { copyIndex.Add(new Tuple(i, sstart - precount, len - copyed)); break; } else { copyIndex.Add(new Tuple(i, sstart - precount, ltmp)); sstart += ltmp; copyed += ltmp; } } } mStream.Position = start; foreach (var vv in copyIndex) { mStream.Write(source[vv.Item1], vv.Item2, vv.Item3); } return this; } public override DataFileSeriserbase Write(List source, long start) { mStream.Position = start; for (int i = 0; i < source.Count; i++) { mStream.Write(source[i], 0, source[i].Length); } return this; } /// /// /// /// /// /// public override DataFileSeriserbase Append(List source, int offset, int len) { //Stopwatch sw = new Stopwatch(); //sw.Start(); List> copyIndex = new List>(); mStream.Position = mStream.Length; int start = offset; int count = 0; int precount = 0; int copyed = 0; for(int i=0;i start) { var ltmp = count - start; if (ltmp > (len - copyed)) { copyIndex.Add(new Tuple(i, start - precount, len - copyed)); break; } else { copyIndex.Add(new Tuple(i, start - precount, ltmp)); start += ltmp; copyed += ltmp; } } } foreach(var vv in copyIndex) { mStream.Write(source[vv.Item1], vv.Item2, vv.Item3); } //sw.Stop(); //LoggerService.Service.Info("LocalFileSeriser", "写入文件耗时:" + sw.ElapsedMilliseconds + " 文件大小:" + len / 1024.0 / 1024.0); return this; } /// /// /// /// public override bool IsOpened() { return mStream != null; } } }