通過反射將物件轉化為檔案,同時反向將檔案還原為物件(適用配置檔案讀寫)
檔案和物件的轉換
在寫程式中經常會使用到配置檔案,而且配置檔案的內容通常還是要賦值給物件,那麼每次如果都給一個特定的類去寫一套讀寫肯定是很不方便,由於工作上的需求所以順便寫了一個通用的只要提供物件即可(ps:要儲存的內容只能是基礎型別,如果物件中有引用型別的將不會被儲存,不過大部分配置檔案的內容應該都是基礎型別就OK了)
/// <summary>
/// 把物件轉化為檔案的內容
/// </summary>
public static class StreamClassToFile
{
/// <summary>
/// 每個物件的分隔
/// </summary>
private static string ClassLog = "`------------------------`" + RowEndLog;
/// <summary>
/// 單個物件的標誌
/// </summary>
private static string SingleHandLog = "Single\n";
/// <summary>
/// 多個物件的標誌
/// </summary>
private static string MoreleHandLog = "More\n";
/// <summary>
/// 分隔符
/// </summary>
private static string CenterLog = "|~|";
/// <summary>
/// 行結尾符
/// </summary>
private static string RowEndLog = "\n";
/// <summary>
/// 欄位開始標識
/// </summary>
private static string FieldStartLog = "<|Fields>";
/// <summary>
/// 欄位結束標識
/// </summary>
private static string FieldEndLog = "<Fields|>";
/// <summary>
/// 開始物件標識
/// </summary>
private static string ObjectStartLog = "<|Object>";
/// <summary>
/// 結束物件標識
/// </summary>
private static string ObjectEndLog = "<Object|>";
/// <summary>
/// 將物件儲存到檔案
/// </summary>
/// <param name="obj"></param>
public static void ObjectToFile(object obj, string fileName)
{
string saveString = SingleHandLog;
saveString += ObjectToString(obj);
using (Stream stream = new FileStream(fileName, FileMode.Create))
{
byte[] data = Encoding.UTF8.GetBytes(saveString);
stream.Write(data, 0, data.Length);
}
}
/// <summary>
/// 將物件轉換為字串
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private static string ObjectToString(object obj)
{
StringBuilder saveString = new StringBuilder();
Type type = obj.GetType();
saveString.Append(ObjectStartLog);
saveString.Append(type.Name + RowEndLog);
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
///儲存欄位
saveString.Append(FieldStartLog + RowEndLog);
foreach (var item in fields)
{
if (IsBasisType(item.FieldType))
saveString.Append(item.FieldType.Name + CenterLog + item.Name + CenterLog + item.GetValue(obj).ToString() + CenterLog + RowEndLog);
}
saveString.Append(FieldEndLog + RowEndLog);
saveString.Append(ObjectEndLog);
return saveString.ToString();
}
/// <summary>
/// 將檔案中的資料讀取並且還原為一個物件(只支援有空建構函式的物件)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileName"></param>
/// <returns></returns>
public static T FileToObject<T>(string fileName)
{
StringBuilder readString = new StringBuilder();
using (StreamReader stream = new StreamReader(fileName, Encoding.UTF8))
{
readString.Append(stream.ReadToEnd());
}
int logindex = readString.ToString().IndexOf(SingleHandLog);
if (logindex == -1 || logindex > SingleHandLog.Length)
{
return default(T);
}
return GetObjectByString<T>(readString.ToString());
}
/// <summary>
/// 根據類字串組裝類
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="readString"></param>
/// <returns></returns>
private static T GetObjectByString<T>(string readString)
{
try
{
Type type = typeof(T);
//type.GetConstructor( BindingFlags.Public, new );
object readobj = Activator.CreateInstance(type);
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
ListData fieldsData = GetFieldValue(readString);///解析所有欄位獲取值
foreach (var item in fields)
{
if (IsBasisType(item.FieldType))
{
item.SetValue(readobj, GetValue(fieldsData[item.Name], item));
}
}
return (T)readobj;
}
catch (Exception ex)
{
return default(T);
}
}
/// <summary>
/// 檢測是否是基礎型別,只支援基礎型別
/// </summary>
/// <param name="typeName">型別名</param>
/// <returns>true為是,false為否</returns>
public static bool IsBasisType(Type type)
{
if (type.IsPrimitive || type.Name == "string" || type.Name == "String" || type.Name == "Guid")
return true;
else
return false;
}
/// <summary>
/// 獲取獲取欄位的資料
/// </summary>
/// <param name="info">欄位資訊</param>
/// <param name="file">總檔案流</param>
/// <returns>值</returns>
private static ListData GetFieldValue(string file)
{
ListData data = new ListData();
string fieldstring = file.ToString();
int startIndex = fieldstring.IndexOf(FieldStartLog);
int endIndex = fieldstring.IndexOf(FieldEndLog);
fieldstring = fieldstring.Substring((startIndex + FieldStartLog.Length), (endIndex - startIndex - FieldStartLog.Length));
string[] fields = fieldstring.Split(RowEndLog.ToCharArray());
string[] values;
foreach (var item in fields)
{
values = item.Split(CenterLog.ToCharArray());
if (values.Length <= 1)
continue;
data.Add(values[CenterLog.Length], values[CenterLog.Length * 2]);
}
return data;
}
/// <summary>
/// 根據欄位的型別變成對應的欄位的值
/// </summary>
/// <param name="value">欄位的值的字串</param>
/// <param name="type">欄位的型別</param>
/// <returns></returns>
private static object GetValue(string value, FieldInfo type)
{
try
{
TypeCode code = GetEnumTypeByString<TypeCode>(type.FieldType.Name);
if (code == TypeCode.Empty && type.FieldType.Name == "Guid")
return new Guid(value);
return Convert.ChangeType(value, code);
}
catch(Exception ex)
{
if(type.Name == "string")
{
return value;
}
else
{
return null;
}
}
}
/// <summary>
/// 批量讀取
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="objs"></param>
/// <param name="fileName"></param>
public static List<T> FileToObjects<T>( string fileName)
{
StringBuilder readString = new StringBuilder();
using (StreamReader stream = new StreamReader(fileName, Encoding.UTF8))
{
readString.Append(stream.ReadToEnd());
}
int logindex = readString.ToString().IndexOf(MoreleHandLog);
if (logindex == -1 || logindex > MoreleHandLog.Length)
{
return default(List<T>);
}
List<T> objs = new List<T>();
////string[] classtrings = readString.ToString().Split(ClassLog.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
string[] classtrings = Regex.Split(readString.ToString(), ClassLog);
int index = 0;
foreach (string item in classtrings)
{
//if(index ++ % ClassLog.Length ==0 && index != classtrings.Length)
if(item.Length != 0)
objs.Add(GetObjectByString<T>(item));
}
return objs;
}
/// <summary>
/// 將多個物件儲存到檔案
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="objs"></param>
/// <param name="fileName"></param>
public static void ObjectsToFile<T>(List<T> objs, string fileName)
{
StringBuilder saveStrings = new StringBuilder();
saveStrings.Append(MoreleHandLog);
foreach (object item in objs)
{
saveStrings.Append(ObjectToString(item));
saveStrings.Append(ClassLog);
}
using (Stream stream = new FileStream(fileName, FileMode.Create))
{
byte[] data = Encoding.UTF8.GetBytes(saveStrings.ToString());
stream.Write(data, 0, data.Length);
}
}
/// <summary>
/// 根據name檢索對應列舉
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <returns></returns>
public static T GetEnumTypeByString<T>(string name)
{
foreach (T item in Enum.GetValues(typeof(T)))
{
if(item.ToString() == name)
{
return item;
}
}
return default(T);
}
/// <summary>
/// 線性插值
/// </summary>
/// <param name="start">起始值</param>
/// <param name="end">終止值</param>
/// <param name="lerp">插值</param>
/// <returns></returns>
public static double Lerp(double start, double end, double lerp)
{
lerp = lerp < 0 ? 0 : lerp;
lerp = lerp > 1 ? 1 : lerp;
return (end + start) * lerp;
}
/// <summary>
/// 根據T型別的列舉的具體V型別的值獲取對應的列舉值
/// </summary>
/// <typeparam name="T">列舉型別</typeparam>
/// <typeparam name="V">列舉型別繼承的型別</typeparam>
/// <param name="value">對應的值</param>
/// <returns>對應的列舉值</returns>
public static T GetEnumTypeByType<T, V>(V value)
{
try
{
TypeCode code = GetEnumTypeByString<TypeCode>(value.GetType().Name);
foreach (T item in Enum.GetValues(typeof(T)))
{
if (Convert.ChangeType(value, code).Equals(value))
{
return item;
}
}
return default(T);
}
catch (Exception)
{
return default(T);
}
}
}
internal class ListData
{
/// <summary>
/// 資料
/// </summary>
private Dictionary<string, string> _data = new Dictionary<string, string>();
/// <summary>
/// 根據名稱獲取值
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string this[string name]
{
get
{
if(_data.Keys.Contains(name))
{
return _data[name];
}
return "";
}
}
/// <summary>
/// 資料
/// </summary>
public Dictionary<string, string> Data
{
get
{
return _data;
}
}
/// <summary>
/// 新增一條資料
/// </summary>
/// <param name="name">屬性名稱</param>
/// <param name="value">屬性的值</param>
public void Add(string name, string value)
{
_data.Add(name, value);
}
}
使用的時候只要呼叫StreamClassToFile.ObjectToFile(物件, 檔名稱包含路徑和名稱);
同時還有ObjectsToFile支援List<T>型別的轉化。
反向的是public static T FileToObject<T>(string fileName)
同樣支援返回List<T>的物件組
相關文章
- 將Schema檔案轉換為Java檔案Java
- 如何將BigWig 檔案轉化為 bed 檔案
- Json檔案轉換為Excel檔案!涉及讀檔案,時間戳轉化,寫文件JSONExcel時間戳
- 如何將.ipynb檔案轉換為.py檔案
- 將檔案轉化為字串的方法字串
- python 將 CVS檔案轉為HTML檔案PythonHTML
- 將bmp檔案壓縮為jpg檔案
- 如何將plist檔案或者陣列NSArray轉化為.json檔案?陣列JSON
- Linux下批量將md檔案轉換為html檔案LinuxHTML
- 將ASD光譜儀的.asd檔案轉為文字檔案
- golang寫入檔案時,覆蓋前檔案(將前檔案清空)Golang
- Matlab將.mat檔案儲存為.txt檔案Matlab
- 反射-通過反射執行配置檔案內容反射
- windows下將隱藏檔案通過命令列改變為普通的顯示檔案Windows命令列
- word檔案怎樣取消只讀模式 把只讀檔案轉化為可編輯檔案模式
- Java中使用Fastjson將JSON檔案轉物件JavaASTJSON物件
- aspose word轉換pdf檔案後將pdf檔案轉換為圖片png
- geoserver將layer打包為shp檔案Server
- PDF檔案轉換為DWF檔案
- 何為配置檔案
- 如何實現將markdown檔案實時轉換為html文件HTML
- Win10系統下將excel檔案轉換為dbf檔案的方法Win10Excel
- 檔案排版(文字檔案讀寫)
- 通過配置檔案(.htaccess)實現檔案上傳
- 辦公利器!用Python快速將任意檔案轉為PDFPython
- 【原創】ASM下的資料檔案轉換為普通檔案ASM
- 如何在 Mac 上使用預覽將 .pdf 檔案更改為 .jpg 檔案Mac
- 安卓手機怎樣將PDF檔案轉為HTML安卓HTML
- 如何將 PowerPoint 簡報轉換為 PDF 檔案?
- Java 將Markdown檔案轉換為Word和PDF文件Java
- java 讀寫 ini 配置檔案Java
- 安卓實用小技巧:將App提取為Apk檔案安卓APPAPK
- 為繞過檢測,攻擊者將惡意Word檔案嵌入到PDF檔案中
- 將Jar檔案製作成exe檔案JAR
- 檔案讀寫
- 如何將Excel檔案解析為json格式ExcelJSON
- 通過mysqlimport定時將遠端文字檔案匯入mysqlMySqlImport
- 直接透過DAO讀、寫Access檔案 (轉)