通过反射将对象转化为文件,同时反向将文件还原为对象(适用配置文件读写)

来源:互联网 发布:js算法题 面试 编辑:程序博客网 时间:2024/06/14 00:07

文件和对象的转换

在写程序中经常会使用到配置文件,而且配置文件的内容通常还是要赋值给对象,那么每次如果都给一个特定的类去写一套读写肯定是很不方便,由于工作上的需求所以顺便写了一个通用的只要提供对象即可(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>的对象组
原创粉丝点击