using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Xml;
using System.IO;
namespace OBJ_FileBus
{
public class Converter
{
public static string BytesToString(byte[] bytes)
{
return FObjBase.Converter.BytesToString(bytes);
}
public static byte[] StringToBytes(string str)
{
return FObjBase.Converter.StringToBytes(str);
}
public static string DateTimeToString(DateTime dt)
{
return FObjBase.Converter.DateTimeToString(dt);
}
}
///
/// 就只是提供给Server 使用
///
public class FileSystemInfoRW
{
#region 获取文件信息
public static bool GetInfo(string path, out FileAttributes fileattr, out DateTime createtime, out DateTime lastwritetime, out int size)
{
string filePath = path;
fileattr = FileAttributes.Normal;
createtime = DateTime.MinValue;
lastwritetime = DateTime.MinValue;
size = 0;
if (Directory.Exists(filePath))
{
DirectoryInfo info = new DirectoryInfo(filePath);
fileattr = FileAttributes.Directory;
createtime = info.CreationTime;
lastwritetime = info.LastWriteTime;
return true;
}
else if (File.Exists(filePath))
{
FileInfo info = new FileInfo(filePath);
fileattr = FileAttributes.Normal;
createtime = info.CreationTime;
lastwritetime = info.LastWriteTime;
size = (int)info.Length;
return true;
}
else
{
return false;
}
}
public static DateTime GetLastWriteTime(string path)
{
FileAttributes fileattr;
DateTime createtime;
DateTime lastwritetime;
int size;
if (GetInfo(path, out fileattr, out createtime, out lastwritetime, out size))
{
return lastwritetime;
}
return DateTime.MinValue;
}
#endregion
#region 获取文件内容
public enum OptFileContentResult
{
///
/// GUID出错
///
GUIDErr,
///
/// 不能写
///
CanntWrite,
///
/// 不存在
///
NoExist,
///
/// 成功
///
OK,
///
/// 正在写,或正在读
///
Doing
}
///
/// 获取文件夹 内容,输出 xml 的byte[]
///
///
///
private OptFileContentResult GetDirectoryContent(string path, ref string guid, UInt16 package_size, out byte[] buf, out UInt32 filesize)
{
filesize = 0;
string filePath = path;
buf = null;
DirectoryInfo dinfo;
XmlDocument xmlDoc = new XmlDocument(); //load xml
XmlElement xmlElem;
dinfo = new DirectoryInfo(filePath);
xmlElem = xmlDoc.CreateElement(FileAttributes.Directory.ToString());
xmlElem.SetAttribute("name", dinfo.Name);
xmlElem.SetAttribute("ctime", dinfo.CreationTime.ToString());
xmlElem.SetAttribute("mtime", dinfo.LastWriteTime.ToString());
xmlDoc.AppendChild(xmlElem);
foreach (FileInfo info in dinfo.GetFiles())
{
XmlElement xmlElem1 = xmlDoc.CreateElement(FileAttributes.Normal.ToString());
xmlElem1.SetAttribute("name", info.Name);
xmlElem1.SetAttribute("ctime", info.CreationTime.ToString());
xmlElem1.SetAttribute("mtime", info.LastWriteTime.ToString());
xmlElem1.SetAttribute("size", info.Length.ToString());
xmlElem.AppendChild(xmlElem1);
}
foreach (DirectoryInfo info in dinfo.GetDirectories())
{
XmlElement xmlElem1 = xmlDoc.CreateElement(FileAttributes.Directory.ToString());
xmlElem1.SetAttribute("name", info.Name);
xmlElem1.SetAttribute("ctime", info.CreationTime.ToString());
xmlElem1.SetAttribute("mtime", info.LastWriteTime.ToString());
xmlElem.AppendChild(xmlElem1);
}
buf = Converter.StringToBytes(xmlDoc.InnerXml);
filesize = (UInt32)buf.Length;
if (package_size < filesize)
{
//需要分多次获取
//创建备份
TempFileRW t = new TempFileRW(path, buf);
guid = t.GUID;
mTempFile.Add(t);
buf = buf.Take(package_size).ToArray();
return OptFileContentResult.Doing;
}
return OptFileContentResult.OK;
}
private OptFileContentResult GetContentPart(string guid, UInt16 package_no, UInt16 package_size, out byte[] buf, out UInt32 filesize)
{
TempFileRW t;
buf = null;
filesize = 0;
string g = guid;
var fws = from _fw in mTempFile where _fw.GUID == g select _fw;
if (fws.Count() > 0)
t = fws.First();
else
{
//出错!!!
return OptFileContentResult.GUIDErr;
}
string filePath = t.Temp;
FileStream sr = new FileStream(filePath, FileMode.Open);
filesize = (UInt32)sr.Length;
int count = package_size;
int offset = package_no * package_size;
if ((offset + count) > sr.Length)
count = (int)(sr.Length - offset);
if (count <= 0)
{
sr.Close();
}
else
{
buf = new byte[count];
sr.Seek(offset, SeekOrigin.Begin);
sr.Read(buf, 0, count);
sr.Close();
}
if ((count + offset) == filesize)
{
//可以删除临时文件了
if (t != null)
{
t.Dispose();
mTempFile.Remove(t);
}
return OptFileContentResult.OK;
}
return OptFileContentResult.Doing;
}
///
/// 获取文件内容
/// 一定要从头获取,当package_size小于filesize,也就是要多次获取时,复制一份临时文件;
/// 读到的数据,都是对这个临时文件读取。
/// 当读取到最后,全部读取完成,删除此文件.
///
/// 分段获取文件,第1次调用 path为文件路径
/// 以后,path为guid
///
/// 路径
/// 文件游标
/// 输出数据
///
private OptFileContentResult GetFileContent(string path, ref string guid, UInt16 package_size, out byte[] buf, out UInt32 filesize)
{
filesize = 0;
buf = null;
string filePath = path;
FileStream sr = new FileStream(filePath, FileMode.Open);
filesize = (UInt32)sr.Length;
UInt32 count = package_size;
if(count>filesize)
count = filesize;
if (count <= 0)
{
sr.Close();
}
else
{
buf = new byte[count];
sr.Read(buf, 0, (int)count);
sr.Close();
}
if(package_size
/// 获取文件夹 或文件 的内容
///
///
///
public OptFileContentResult GetContent(string path, ref string guid, UInt16 package_no, UInt16 package_size, out byte[] buf, out UInt32 filesize)
{
buf = null;
filesize = 0;
if (package_no == 0)
{
if (Directory.Exists(path))
{
return GetDirectoryContent(path, ref guid, package_size, out buf, out filesize);
}
else if (File.Exists(path))
{
return GetFileContent(path, ref guid, package_size, out buf, out filesize);
}
else
{
return OptFileContentResult.NoExist;
}
}
else
{
return GetContentPart(guid, package_no, package_size, out buf, out filesize);
}
}
#endregion
#region 写文件内容
///
/// 设置文件内容,当为虚拟文件时,不操作,直接返回
///
///
///
///
///
///
///
public OptFileContentResult SetFileContent(string path, ref string guid, UInt32 filesize, UInt16 package_size, UInt16 package_no, byte[] context)
{
TempFileRW t;
string filePath = path;
if (package_no == 0)
{
//创建临时文件
t = new TempFileRW();
guid = t.GUID;
mTempFile.Add(t);
}
else
{
string g = guid;
var fws = from _fw in mTempFile where _fw.GUID == g select _fw;
if (fws.Count() > 0)
t = fws.First();
else
{
//出错!!!
return OptFileContentResult.GUIDErr;
}
}
try
{
FileStream sr = new FileStream(TempFileRW.TempDir+@"\" + guid, FileMode.OpenOrCreate);
sr.Seek(package_no * package_size, SeekOrigin.Begin);
sr.Write(context, 0, context.Length);
sr.Flush();
sr.Close();
}
catch
{
return OptFileContentResult.CanntWrite;
}
if ((package_no * package_size + context.Length) >= filesize)
{
//全部数据上传完
try
{
if (File.Exists(path))
{
//当文件已经存在,删除
File.Delete(path);
}
else
{
//文件不存在,创建文件夹
string dir = Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
Directory.CreateDirectory(dir);
}
File.Move(TempFileRW.TempDir + @"\" + guid, path);
}
catch
{
//可以删除临时文件了
t.Dispose();
mTempFile.Remove(t);
return OptFileContentResult.CanntWrite;
}
//可以删除临时文件了
t.Dispose();
mTempFile.Remove(t);
return OptFileContentResult.OK;
}
else
{
return OptFileContentResult.Doing;
}
}
List mTempFile = new List();
class TempFileRW
{
public TempFileRW()
{
//产生临时文件
GUID = Guid.NewGuid().ToString();
if (!Directory.Exists(TempDir))
Directory.CreateDirectory(TempDir);
}
public TempFileRW(string path)
{
this.path = path;
//产生临时文件
GUID = Guid.NewGuid().ToString();
FileInfo info = new FileInfo(path);
if (!Directory.Exists(TempDir))
Directory.CreateDirectory(TempDir);
info.CopyTo(TempDir+@"\" + GUID);
}
public TempFileRW(string path, byte[] buf)
{
//产生临时文件
GUID = Guid.NewGuid().ToString();
if (!Directory.Exists(TempDir))
Directory.CreateDirectory(TempDir);
this.path = path;
FileStream fs = new FileStream(Temp, FileMode.Create);
fs.Write(buf, 0, buf.Length);
fs.Flush();
fs.Close();
}
public string GUID;
public string path;
public string Temp {
get {
return TempDir+@"\" + GUID;
}
}
public void Dispose()
{
if (File.Exists(Temp))
File.Delete(Temp);
}
public const string TempDir = @"filebus\tmp";
}
#endregion
}
}