【问题标题】:Saving data to a file in C#在 C# 中将数据保存到文件中
【发布时间】:2012-05-07 10:06:39
【问题描述】:

所以我目前正在为探路者角色扮演游戏制作一个自动角色表的项目,并且不知道如何保存数据。我想将所有变量的当前值保存到扩展名为 .pfcsheet 的文件中,稍后再打开。我四处搜索,找不到说明如何执行此操作的内容,只是如何保存文本框的内容。我尝试使用 saveFileDialog 控件,但它一直给我一个“文件名无效”的错误,似乎没有人知道为什么。

【问题讨论】:

  • 您可以将对象序列化为 XML 字符串,然后将该字符串写入具有您选择的名称和扩展名的文件。
  • @xbonez 我有一种感觉,如果他们在使用文件保存对话框时遇到困难,那么序列化是不可能的。教程可能是有序的。
  • @MichaelTodd:添加了更多详细信息作为答案。确定序列化可能有点棘手。
  • 感谢帮助我研究序列化的人。
  • 为了以后参考,当您开始实际项目时,请始终指定文件的格式是否由某些接口控制文档固定。请考虑格式的向前和向后兼容性。而且,无论如何,在求助于在线论坛之前,请更加努力地进行自己的研究......

标签: c# file save


【解决方案1】:

我刚刚写了a blog post on saving an object's data to Binary, XML, or Json。听起来您可能想要使用二进制序列化,但也许您希望在应用程序之外编辑文件,在这种情况下 XML 或 Json 可能会更好。以下是各种格式的功能。有关详细信息,请参阅我的博文。

二进制

/// <summary>
/// Writes the given object instance to a binary file.
/// <para>Object type (and all child types) must be decorated with the [Serializable] attribute.</para>
/// <para>To prevent a variable from being serialized, decorate it with the [NonSerialized] attribute; cannot be applied to properties.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the XML file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the XML file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append = false)
{
    using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
    {
        var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        binaryFormatter.Serialize(stream, objectToWrite);
    }
}

/// <summary>
/// Reads an object instance from a binary file.
/// </summary>
/// <typeparam name="T">The type of object to read from the XML.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the binary file.</returns>
public static T ReadFromBinaryFile<T>(string filePath)
{
    using (Stream stream = File.Open(filePath, FileMode.Open))
    {
        var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        return (T)binaryFormatter.Deserialize(stream);
    }
}

XML

需要将 System.Xml 程序集包含在您的项目中。

/// <summary>
/// Writes the given object instance to an XML file.
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute.</para>
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToXmlFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
    TextWriter writer = null;
    try
    {
        var serializer = new XmlSerializer(typeof(T));
        writer = new StreamWriter(filePath, append);
        serializer.Serialize(writer, objectToWrite);
    }
    finally
    {
        if (writer != null)
            writer.Close();
    }
}

/// <summary>
/// Reads an object instance from an XML file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the XML file.</returns>
public static T ReadFromXmlFile<T>(string filePath) where T : new()
{
    TextReader reader = null;
    try
    {
        var serializer = new XmlSerializer(typeof(T));
        reader = new StreamReader(filePath);
        return (T)serializer.Deserialize(reader);
    }
    finally
    {
        if (reader != null)
            reader.Close();
    }
}

Json

您必须包含对 Newtonsoft.Json 程序集的引用,该程序集可从 Json.NET NuGet Package 获得。

/// <summary>
/// Writes the given object instance to a Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [JsonIgnore] attribute.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
    TextWriter writer = null;
    try
    {
        var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite);
        writer = new StreamWriter(filePath, append);
        writer.Write(contentsToWriteToFile);
    }
    finally
    {
        if (writer != null)
            writer.Close();
    }
}

/// <summary>
/// Reads an object instance from an Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the Json file.</returns>
public static T ReadFromJsonFile<T>(string filePath) where T : new()
{
    TextReader reader = null;
    try
    {
        reader = new StreamReader(filePath);
        var fileContents = reader.ReadToEnd();
        return JsonConvert.DeserializeObject<T>(fileContents);
    }
    finally
    {
        if (reader != null)
            reader.Close();
    }
}

示例

// To save the characterSheet variable contents to a file.
WriteToBinaryFile<CharacterSheet>("C:\CharacterSheet.pfcsheet", characterSheet);

// To load the file contents back into a variable.
CharacterSheet characterSheet = ReadFromBinaryFile<CharacterSheet>("C:\CharacterSheet.pfcsheet");

【讨论】:

  • 你有点晚了,不是吗?您回答的问题是 2012 年提出的。
  • @RobertHarvey 当然,对于 OP,但其他人(比如我自己)仍然一直在通过搜索引擎找到这篇文章,所以有更多的答案和例子来学习总是很好的。
  • @deadlydog 感谢您提供出色的代码示例。我想知道如果无法在 Read 函数中读取多个序列化实例,您为什么还要在 Write 函数中包含 bool append。换句话说,append 不会总是错误的,因为你不能从同一个文件中读取多个写入吗?
  • @ZX9 是的,你是对的,如果你打算稍后使用它来读取序列化,你可能不需要append bool。我只是将它包括在内,以防用户偶然想将一堆不同的实例转储到一个 xml 文件中,以便稍后人工阅读该文件。
  • 非常好,轻松为我节省了几个小时 - 谢谢。
【解决方案2】:

我想你可能想要这样的东西

// Compose a string that consists of three lines.
string lines = "First line.\r\nSecond line.\r\nThird line.";

// Write the string to a file.
System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test.txt");
file.WriteLine(lines);

file.Close();

【讨论】:

    【解决方案3】:

    查看XMLSerializer 类。

    如果您想保存对象的状态并能够在其他时间轻松地重新创建它们,那么序列化是您的最佳选择。

    对其进行序列化,以便返回完整格式的 XML。使用StreamWriter 类将其写入文件。

    稍后,您可以读入文件的内容,并将其与您要填充的对象的实例一起传递给序列化程序类,序列化程序也会负责反序列化。

    这是取自Microsoft Support的代码sn-p:

    using System;
    
    public class clsPerson
    {
      public  string FirstName;
      public  string MI;
      public  string LastName;
    }
    
    class class1
    { 
       static void Main(string[] args)
       {
          clsPerson p=new clsPerson();
          p.FirstName = "Jeff";
          p.MI = "A";
          p.LastName = "Price";
          System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
    
          // at this step, instead of passing Console.Out, you can pass in a 
          // Streamwriter to write the contents to a file of your choosing.
          x.Serialize(Console.Out, p);
    
    
          Console.WriteLine();
          Console.ReadLine();
       }
    } 
    

    【讨论】:

    • 这个。除了序列化允许您将对象的当前状态作为可持久化数据发出之外,XML 序列化还生成一个可以称为“人类可消费”的文件,并且很容易将其作为输入解析到另一个程序中。
    【解决方案4】:

    这是一个类似于 Sachin 的简单示例。建议对非托管文件资源使用“using”语句:

            // using System.IO;
            string filepath = @"C:\test.txt";
            using (StreamWriter writer = new StreamWriter(filepath))
            {
                writer.WriteLine("some text");
            }
    

    using Statement (C# Reference)

    【讨论】:

      【解决方案5】:

      这是 MSDN 上关于如何将文本写入文件的指南的文章:

      http://msdn.microsoft.com/en-us/library/8bh11f1k.aspx

      我会从那里开始,然后在您继续开发时发布更多、更具体的问题。

      【讨论】:

        【解决方案6】:

        一个班轮:

        System.IO.File.WriteAllText(@"D:\file.txt", content);
        

        如果文件不存在,它会创建文件,如果存在则覆盖它。确保您有适当的权限写入该位置,否则您将收到异常。

        https://msdn.microsoft.com/en-us/library/ms143375%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

        Write string to text file and ensure it always overwrites the existing content.

        【讨论】:

          【解决方案7】:

          从 System.IO 命名空间(尤其是 File 或 FileInfo 对象)开始应该可以帮助您入门。

          http://msdn.microsoft.com/en-us/library/system.io.file.aspx

          http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-09
            • 2021-11-20
            • 1970-01-01
            • 2021-08-18
            相关资源
            最近更新 更多