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