简体   繁体   中英

Saving data to a file in C#

So i am currently working on a project to make an automated Character Sheet for the Pathfinder Roleplaying Game, and am at a loss as to how to save the data. I want to save the current value of all my variables to a file with the extension .pfcsheet and open it later. I've googled around and can not find something that says how to do this, just how to save the contents of a text box. I tried using the saveFileDialog control but it keeps giving me a "file name is not valid" error and nobody seems to know why.

I just wrote a blog post on saving an object's data to Binary, XML, or Json . It sounds like you probably want to use Binary serialization, but perhaps you want the files to be edited outside of your app, in which case XML or Json might be better. Here are the functions to do it in the various formats. See my blog post for more details.

Binary

/// <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

Requires the System.Xml assembly to be included in your project.

/// <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

You must include a reference to Newtonsoft.Json assembly, which can be obtained from the 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();
    }
}

Example

// 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");

I think you might want something like this

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

Look into the XMLSerializer class.

If you want to save the state of objects and be able to recreate them easily at another time, serialization is your best bet.

Serialize it so you are returned the fully-formed XML. Write this to a file using the StreamWriter class.

Later, you can read in the contents of your file, and pass it to the serializer class along with an instance of the object you want to populate, and the serializer will take care of deserializing as well.

Here's a code snippet taken from Microsoft Support :

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

Here is a simple example similar to Sachin's. It's recommended to use a "using" statement on the unmanaged file resource:

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

using Statement (C# Reference)

Here's an article from MSDN on a guide for how to write text to a file:

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

I'd start there, then post additional, more specific questions as you continue your development.

Starting with the System.IO namespace (particularly the File or FileInfo objects) should get you started.

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

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

One liner:

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

It creates the file if it doesn't exist and overwrites it if it exists. Make sure you have appropriate privileges to write to the location, otherwise you will get an exception.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM