C# 如何保存人类可读的文件
目前,我有一个应用程序,它使用二进制序列化程序将一个或两个基本类中的多个属性读写到.txt文件中 我已经在记事本中打开了.txt文件,因为它是为应用程序格式化的,所以对人眼来说不是很可读,对我来说也不是 我听说过使用XML,但我的大部分搜索似乎过于复杂 我试图保存的数据只是“Person.cs”类的集合,只不过是一个名称和地址,所有私有字符串都带有属性,并标记为可序列化 以便于个人阅读的方式保存数据的最佳方式是什么?它还使直接在文件中对应用程序的数据进行小的更改变得更容易,而不必加载、更改和保存数据 编辑: 我添加了当前保存和加载数据的方式,我的_userCollection正如它所建议的那样,user/n成员是一个整数C# 如何保存人类可读的文件,c#,.net,xml-serialization,C#,.net,Xml Serialization,目前,我有一个应用程序,它使用二进制序列化程序将一个或两个基本类中的多个属性读写到.txt文件中 我已经在记事本中打开了.txt文件,因为它是为应用程序格式化的,所以对人眼来说不是很可读,对我来说也不是 我听说过使用XML,但我的大部分搜索似乎过于复杂 我试图保存的数据只是“Person.cs”类的集合,只不过是一个名称和地址,所有私有字符串都带有属性,并标记为可序列化 以便于个人阅读的方式保存数据的最佳方式是什么?它还使直接在文件中对应用程序的数据进行小的更改变得更容易,而不必加载、更改和保存
#region I/O Operations
public bool SaveData()
{
try
{
//Open the stream using the Data.txt file
using (Stream stream = File.Open("Data.txt", FileMode.Create))
{
//Create a new formatter
BinaryFormatter bin = new BinaryFormatter();
//Copy data in collection to the file specified earlier
bin.Serialize(stream, _userCollection);
bin.Serialize(stream, nMember);
bin.Serialize(stream, nUser);
//Close stream to release any resources used
stream.Close();
}
return true;
}
catch (IOException ex)
{
throw new ArgumentException(ex.ToString());
}
}
public bool LoadData()
{
//Check if file exsists, otherwise skip
if (File.Exists("Data.txt"))
{
try
{
using (Stream stream = File.Open("Data.txt", FileMode.Open))
{
BinaryFormatter bin = new BinaryFormatter();
//Copy data back into collection fields
_userCollection = (List<User>)bin.Deserialize(stream);
nMember = (int)bin.Deserialize(stream);
nUser = (int)bin.Deserialize(stream);
stream.Close();
//Sort data to ensure it is ordered correctly after being loaded
_userCollection.Sort();
return true;
}
}
catch (IOException ex)
{
throw new ArgumentException(ex.ToString());
}
}
else
{
//Console.WriteLine present for testing purposes
Console.WriteLine("\nLoad failed, Data.txt not found");
return false;
}
}
#区域I/O操作
公共bool SaveData()
{
尝试
{
//使用Data.txt文件打开流
使用(Stream=File.Open(“Data.txt”,FileMode.Create))
{
//创建一个新的格式化程序
BinaryFormatter bin=新的BinaryFormatter();
//将集合中的数据复制到前面指定的文件
序列化(流,_userCollection);
序列化(流,n成员);
序列化(流,用户);
//关闭流以释放所使用的任何资源
stream.Close();
}
返回true;
}
捕获(IOEX异常)
{
抛出新ArgumentException(例如ToString());
}
}
公共bool LoadData()
{
//检查文件是否存在,否则跳过
如果(File.Exists(“Data.txt”))
{
尝试
{
使用(Stream=File.Open(“Data.txt”,FileMode.Open))
{
BinaryFormatter bin=新的BinaryFormatter();
//将数据复制回集合字段
_userCollection=(列表)bin.Deserialize(流);
nMember=(int)bin.反序列化(流);
用户=(int)bin.反序列化(流);
stream.Close();
//对数据进行排序,以确保加载后数据的顺序正确
_userCollection.Sort();
返回true;
}
}
捕获(IOEX异常)
{
抛出新ArgumentException(例如ToString());
}
}
其他的
{
//Console.WriteLine用于测试目的
Console.WriteLine(“\n加载失败,找不到Data.txt”);
返回false;
}
}
您可以实现自己的PersonWriter
,它将StreamWriter
作为构造函数参数,并具有Write
方法,该方法将IList
作为输入,以解析出一个好的文本表示
例如:
public class PersonsWriter : IDisposable
{
private StreamWriter _wr;
public PersonsWriter(IList<Person> persons, StreamWriter writer)
{
this._wr = writer;
}
public void Write(IList<Persons> people) {
foreach(Person dude in people)
{
_wr.Write(@"{0} {1}\n{2}\n{3} {4}\n\n",
dude.FirstName,
dude.LastName,
dude.StreetAddress,
dude.ZipCode,
dude.City);
}
}
public void Dispose()
{
_wr.Flush();
_wr.Dispose();
}
}
公共类PersonWriter:IDisposable
{
私人流动写手(西铁);
公共人物作家(IList人物、StreamWriter作家)
{
这个._wr=编写器;
}
公共无效写入(IList人员){
foreach(人物中的人物)
{
_Write(@“{0}{1}\n{2}\n{3}{4}\n\n”,
都德,名字,
都德,姓,
都德,街道地址,
都德,ZipCode,
都德,城市);
}
}
公共空间处置()
{
_wr.Flush();
_wr.Dispose();
}
}
使用XmlSerializer其实并不复杂。查看此MSDN页面以获取示例:用XMLSerializer替换BinaryFormatter并运行相同的代码
您需要做的唯一更改是BinaryFormatter采用空构造函数,而对于XMLSerializer,您需要在构造函数中声明类型:
XmlSerializer serializer = new XmlSerializer(typeof(Person));
试试
它将对象序列化为XML,并且非常易于使用,如果您希望在Windows环境中在人机可读性之间取得良好的折衷,可以编写CSV读写器 也会加载到Excel中 这里有一个关于它的讨论: 编辑 那是一篇C#文章。。。它只是在URL中有一个令人困惑的“C”。是人类可读标记的另一个选项,也很容易解析。c#以及几乎所有其他流行语言都有可用的库。下面是yaml的示例:
invoice: 34843
date : 2001-01-23
bill-to: &id001
given : Chris
family : Dumars
address:
lines: |
458 Walkman Dr.
Suite #292
city : Royal Oak
state : MI
postal : 48046
我真的认为您应该使用XML(查看DataContractSerializer)。没那么复杂。您甚至可以用XMLSerializer替换BinarySerializer,然后继续 但是,如果您仍然不想这样做,可以编写一个带分隔符的文本文件。然后您必须编写自己的reader方法(尽管它几乎可以使用split方法)
//在Person类中:
公共重写字符串ToString()
{
List propValues=新列表();
//获取类型。
Type t=this.GetType();
//循环浏览属性。
foreach(t.GetProperties()中的PropertyInfo p)
{
add(“{0}:={1}”,p.Name,p.GetValue(o,null));
}
返回字符串.Join(“,”.propValues.ToArray())
}
使用(System.IO.TextWriter tw=new System.IO.StreamWriter(“output.txt”))
{
tw.WriteLine(person.ToString());
}
坦率地说,作为一个人,我觉得XML不是那么可读。事实上,它并不是为人类设计的
如果您想要一种人类可读的格式,那么您必须构建它
比如说,您有一个Person类,它的属性包括名字、姓氏和SSN。创建您的文件,并让它写出3行,描述为t
//Inside the Person class:
public override string ToString()
{
List<String> propValues = new List<String>();
// Get the type.
Type t = this.GetType();
// Cycle through the properties.
foreach (PropertyInfo p in t.GetProperties())
{
propValues.add("{0}:={1}", p.Name, p.GetValue(o, null));
}
return String.Join(",". propValues.ToArray())
}
using (System.IO.TextWriter tw = new System.IO.StreamWriter("output.txt"))
{
tw.WriteLine(person.ToString());
}
First Name-------Stephen
Last Name -------Wrighton
SSN -------------XXX-XX-XXXX