C# 保存通用列表
有没有办法将列表保存到磁盘上?我尝试了数据协定序列化程序,但它总是生成一个空列表C# 保存通用列表,c#,generics,C#,Generics,有没有办法将列表保存到磁盘上?我尝试了数据协定序列化程序,但它总是生成一个空列表 public static List<T> Load<T>() where T : class,new() { var serializer = new DataContractSerializer(typeof(List<T>)); string path = HttpContext.Current.Server.MapPath
public static List<T> Load<T>() where T : class,new()
{
var serializer = new DataContractSerializer(typeof(List<T>));
string path = HttpContext.Current.Server.MapPath("~/App_Data/" + typeof(T).ToString() + ".xml");
if (!System.IO.File.Exists(path))
{
return new List<T>();
}
else
{
using (var s = new System.IO.FileStream(path, System.IO.FileMode.Open))
{
return serializer.ReadObject(s) as List<T>;
}
}
}
public static void Save<T>(List<T> data) where T : class,new()
{
var serializer = new DataContractSerializer(typeof(List<T>));
Enumerate<T>(data);
string path = HttpContext.Current.Server.MapPath("~/App_Data/" + typeof(T).ToString() + ".xml");
using (var s = new System.IO.FileStream(path, System.IO.FileMode.Create))
{
serializer.WriteObject(s, data);
}
}
公共静态列表加载(),其中T:class,new()
{
var serializer=新的DataContractSerializer(typeof(List));
字符串路径=HttpContext.Current.Server.MapPath(“~/App_Data/”+typeof(T).ToString()+”.xml”);
如果(!System.IO.File.Exists(path))
{
返回新列表();
}
其他的
{
使用(var s=new System.IO.FileStream(path,System.IO.FileMode.Open))
{
将serializer.ReadObject作为列表返回;
}
}
}
公共静态无效保存(列表数据),其中T:class,new()
{
var serializer=新的DataContractSerializer(typeof(List));
列举(数据);
字符串路径=HttpContext.Current.Server.MapPath(“~/App_Data/”+typeof(T).ToString()+”.xml”);
使用(var s=new System.IO.FileStream(path,System.IO.FileMode.Create))
{
serializer.WriteObject(多个,数据);
}
}
您可能需要使用JavaScriptSerializer
var json = new JavaScriptSerializer().Serialize(thing);
JSON列表是通用的
更新:TimS Json.NET声称Ass是更好的序列化程序,所以如果添加第三方库是一个选项,那么二进制序列化程序呢
public static void SerializeToBin(object obj, string filename)
{
Directory.CreateDirectory(Path.GetDirectoryName(filename));
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
using (FileStream fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
bf.Serialize(fs, obj);
}
}
public static T DeSerializeFromBin<T>(string filename) where T : new()
{
if (File.Exists(filename))
{
T ret = new T();
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
ret = (T)bf.Deserialize(fs);
}
return ret;
}
else
throw new FileNotFoundException(string.Format("file {0} does not exist", filename));
}
publicstaticvoid序列化tobin(objectobj,stringfilename)
{
CreateDirectory(Path.GetDirectoryName(filename));
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf=new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
使用(FileStream fs=newfilestream(文件名,FileMode.OpenOrCreate,FileAccess.ReadWrite))
{
bf.序列化(fs,obj);
}
}
公共静态T反序列化frombin(字符串文件名),其中T:new()
{
if(File.Exists(filename))
{
T ret=新的T();
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf=new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
使用(FileStream fs=newfilestream(文件名,FileMode.Open,FileAccess.Read))
{
ret=(T)bf.反序列化(fs);
}
返回ret;
}
其他的
抛出新的FileNotFoundException(string.Format(“文件{0}不存在”,filename));
}
根据您尝试执行的操作,密钥也可能是您的T类,确保它使用适当的[DataContract]
和[DataMember]
属性进行修饰。下面是一个基于您的代码的工作示例(但是,如果您不想在代码之外使用持久化文件,您可能会在二进制序列化程序中发现更好的性能):
[DataContract]
公共类Mydata
{
[数据成员]
公共int Id{get;set;}
[数据成员]
公共字符串名称{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
List myData=new List();
添加(新的myData(){Id=1,Name=“Object 1”});
添加(新的myData(){Id=2,Name=“Object 2”});
字符串路径=path.GetDirectoryName(System.Reflection.Assembly.getExecutionGassembly().Location)+@“\”+typeof(Mydata).ToString()+“.xml”;
保存(myData,路径);
List myNewData=Load(路径);
Console.WriteLine(myNewData.Count);
Console.ReadLine();
}
公共静态列表加载(字符串文件名),其中T:class
{
var serializer=新的DataContractSerializer(typeof(List));
如果(!System.IO.File.Exists(filename))
{
返回新列表();
}
其他的
{
使用(var s=new System.IO.FileStream(filename,System.IO.FileMode.Open))
{
将serializer.ReadObject作为列表返回;
}
}
}
公共静态无效保存(列表,字符串文件名)
{
var serializer=新的DataContractSerializer(typeof(List));
使用(FileStream fs=newfilestream(filename,FileMode.Create))
{
使用(XmlDictionaryWriter=XmlDictionaryWriter.CreateTextWriter(fs))
{
serializer.WriteObject(writer,list);
}
}
}
}
副本的代码中有错误。@tekan这个问题似乎不存在。枚举(数据)
方法做什么?编译器是否需要枚举(数据)
而不是枚举(数据)
?@quillbreaker您尝试序列化的T
类型是什么?您的代码是否可以处理简单的类型,如string或int?您是否看到生成的文件包含数据,或者序列化过程中出现错误?@quillbreaker您知道可以按编辑按钮。无论如何。你的代码会出现很多危险信号<代码>as强制转换可能会隐藏错误T
未包含在内,因此我不知道它的属性是否正确<代码>枚举不包括在代码列表中where new()
是完全多余的(甚至可能是where类
)。您确定返回新列表()
代码分支没有运行吗?您可能没有写入App\u Data
@TimS的权限。甚至微软团队也同意这一点。所有新的微软开源软件都使用Json.Net。@TimS。更新了答案。我查看了Json.Net,它为我列出了空对象的列表。关于这个问题,这里有更详细的答案,同意Json.Net是可取的,如果可以的话。我已经解决了空对象列表问题,目前正在使用JSON.net序列化程序。我很快就会接受的。
[DataContract]
public class Mydata
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Mydata> myData = new List<Mydata>();
myData.Add(new Mydata() { Id = 1, Name = "Object 1" });
myData.Add(new Mydata() { Id = 2, Name = "Object 2" });
string path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\" + typeof(Mydata).ToString() + ".xml";
Save<Mydata>(myData, path);
List<Mydata> myNewData = Load<Mydata>(path);
Console.WriteLine(myNewData.Count);
Console.ReadLine();
}
public static List<T> Load<T>(string filename) where T : class
{
var serializer = new DataContractSerializer(typeof(List<T>));
if (!System.IO.File.Exists(filename))
{
return new List<T>();
}
else
{
using (var s = new System.IO.FileStream(filename, System.IO.FileMode.Open))
{
return serializer.ReadObject(s) as List<T>;
}
}
}
public static void Save<T>(List<T> list, string filename)
{
var serializer = new DataContractSerializer(typeof(List<T>));
using (FileStream fs = new FileStream(filename, FileMode.Create))
{
using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs))
{
serializer.WriteObject(writer, list);
}
}
}
}