如何保存人类可读文件

时间:2009-12-29 22:24:22

标签: c# .net xml-serialization

目前我有一个应用程序,它使用二进制序列化程序从一个或两个基本类读取和写入几个属性到.txt文件。

我在NotePad中打开了.txt文件,因为它为应用程序设置了格式,它对人眼来说不是很容易理解,不管怎样对我来说不是= D

我听说过使用XML,但我的大部分搜索工作似乎都过于复杂。

我试图保存的数据类型只是“Person.cs”类的集合,只不过是名称和地址,所有私有字符串但具有属性并标记为Serializable。

以一种人们可以轻松阅读的方式实际保存数据的最佳方法是什么?它还可以更容易地直接在文件中对应用程序的数据进行小的更改,而不必加载,更改并保存它。

编辑:

我添加了当前保存和加载数据的方式,我的_userCollection正如它所暗示的那样,nUser / nMember是一个整数。

#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;
        }
    }

8 个答案:

答案 0 :(得分:6)

用XMLSerializer替换BinaryFormatter并运行相同的代码。

您需要做的唯一更改是BinaryFormatter采用空构造函数,而对于XMLSerializer,您需要在构造函数中声明类型:

XmlSerializer serializer = new XmlSerializer(typeof(Person));

答案 1 :(得分:3)

您可以实现自己的PersonsWriter,它将StreamWriter作为构造函数参数,并使用Write方法将IList<Person>作为输入来解析出一个好文本表示。

例如:

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();
    }
}

答案 2 :(得分:3)

使用XmlSerializer并不是很复杂。请查看此MSDN页面以获取示例:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

答案 3 :(得分:1)

YAML是人类可读标记的另一个选项,也很容易解析。有可用于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

答案 4 :(得分:1)

坦率地说,作为一个人,我发现XML并不是那么可读。事实上,它并非真正被人类阅读。

如果你想要一个人类可读的格式,那么你必须构建它。

比如说,你有一个Person类,它有一个名字,一个姓氏和一个SSN作为属性。创建你的文件,让它写出3行,前五十个字段的描述(从头开始的随机数)然后用字符51写入值start。

这将产生一个看起来像的文件:

First Name-------Stephen
Last Name -------Wrighton
SSN -------------XXX-XX-XXXX

然后,读回来,你的程序会知道数据从每一行开始的位置,以及每行的用途(程序会知道第3行是SSN值)。

但请记住,要真正获得人类的可读性,就会牺牲数据的可移植性。

答案 5 :(得分:0)

尝试DataContractSerializer

它将对象序列化为XML并且非常易于使用

答案 6 :(得分:0)

如果您希望在Windows环境中人机阅读与机器可读之间做出妥协,请编写CSV阅读器编写器

也加载到Excel中。

这里有一个讨论:

http://knab.ws/blog/index.php?/archives/3-CSV-file-parser-and-writer-in-C-Part-1.html

修改

这是一篇C#文章......它只是令人困惑地在网址中有“C”。

答案 7 :(得分:0)

我真的认为你应该使用XML(查看DataContractSerializer)。它并不复杂。您甚至可以用XMLSerializer替换BinarySerializer并继续。

但是,如果您仍然不想这样做,则可以编写分隔的文本文件。然后你必须编写自己的阅读器方法(尽管它几乎只能使用split方法)。

//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());
}