Сохранять данные при сериализации объектов/десериализации, которые были посланы ему


Я создал следующий класс для сохранения данных при сериализации объектов/десериализации, которые были посланы ему. Я хотел бы знать, если есть лучший способ написания этого класса, или если мой класс хорошо как есть.

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;

namespace Education_PersistingData
{
public class PersistData<T>
{
    private readonly T _obj;
    private readonly string _filePath;
    private readonly string _fileName;

    public PersistData(T obj, string filePath, string fileName)
    {
        this._obj = obj;
        this._filePath = filePath;
        this._fileName = fileName;
    }

    /// <summary>
    /// Serializes objects to a SOAP .xml format
    /// </summary>
    public void SerializeToSoapFormat()
    {
        try
        {
            SoapFormatter soapFormatter = new SoapFormatter();
            Stream dataStream = File.Create(_filePath + _fileName);
            soapFormatter.Serialize(dataStream, _obj);
            dataStream.Close();
        }
        catch (IOException ex)
        {
            throw new IOException(ex.Message);
        }
    }

    /// <summary>
    /// Serializes objects to a Binary .txt format
    /// </summary>
    public void SerializeToBinaryFormat()
    {
        try
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            Stream dataStream = File.Create(_filePath + _fileName);
            binaryFormatter.Serialize(dataStream, _obj);
            dataStream.Close();
        }
        catch (IOException ex)
        {
            throw new IOException(ex.Message);
        }
    }

    /// <summary>
    /// Deserializes a SOAP .xml file format
    /// </summary>
    /// <returns>Deserialized object</returns>
    public T DeserializeSoapFormat()
    {
        try
        {
            SoapFormatter soapFormatter = new SoapFormatter();
            Stream dataStream = File.OpenRead(_filePath + _fileName);
            T result = (T)soapFormatter.Deserialize(dataStream);
            dataStream.Close();
            return result;
        }
        catch (IOException ex)
        {
            throw new IOException(ex.Message);
        }
    }

    /// <summary>
    /// Deserializes a Binary .txt file format
    /// </summary>
    /// <returns>Deserialized object</returns>
    public T DeserializeBinaryFormat()
    {
        try
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            Stream dataStream = File.OpenRead(_filePath + _fileName);
            T result = (T)binaryFormatter.Deserialize(dataStream);
            dataStream.Close();
            return result;
        }
        catch (IOException ex)
        {
            throw new IOException(ex.Message);
        }
    }
}
}


Комментарии
3 ответа

Нет смысла ловить IOException и затем бросать новое исключение. Вы только свободная информация. Либо справиться с этим или удалить попробовать-поймать вообще.

Кроме того, использовать помощью всегда распоряжаться интерфейс IDisposable объектов.

7
ответ дан 14 июля 2011 в 07:07 Источник Поделиться

Вы могли бы попробовать сделать класс универсальным, с тем ограничением, что он должен реализовать интерфейс iformatter, как класс soapformatter и класс binaryformatter делает.

public class PersistData<T, TY> where TY : IFormatter, new()
{
private readonly T _obj;
private readonly string _filePath;
private readonly string _fileName;

public PersistData(T obj, string filePath, string fileName)
{
this._obj = obj;
this._filePath = filePath;
this._fileName = fileName;
}

public void Serialize()
{
try
{
IFormatter formatter = new TY();

using (Stream dataStream = File.Create(_filePath + _fileName))
{
formatter.Serialize(dataStream, _obj);
}
}
catch (IOException ex)
{
// log and handle error
}
}

public T Deserialize()
{
try
{
IFormatter formatter = new TY();

using (Stream dataStream = File.OpenRead(_filePath + _fileName))
{
return (T) formatter.Deserialize(dataStream);
}
}
catch (IOException ex)
{
// log and handle error
}
}

}

6
ответ дан 14 июля 2011 в 08:07 Источник Поделиться

Судя по пути вы использовали класс, я бы сказал, что нет смысла иметь путь к файлу и именем раздельные. Вместо этого, я бы просто пройти полный путь. Таким образом, Вы имеете всю необходимую информацию без необходимости объединить две строки каждый раз, когда вы их используете (если большой объем может немного повлиять на производительность). Если вы обнаружите, вам нужно их отдельно в некоторых случаях, вы всегда можете восстановить их с помощью вспомогательных методов в системе.ИО.Путь.

Кроме того, после форматирования обычно используется, я бы повторно использовать их. Так что вместо создания нового форматирования каждый раз, когда вы хотите сериализовать/десериализовать некоторые данные, я бы поставил следующий (или нечто подобное) в верхней части вашего класса:

private static readonly SoapFormatter SharedSoapFormatter = new SoapFormatter();
private static readonly BinaryFormatter SharedBinaryFormatter = new BinaryFormatter();

Последнее замечание я хотел бы сделать, это использовать через инструкция при работе с потоками. Это намного красивее и делает распоряжение поток более явными. т. е.

using (var stream = File.Create(filePath))
{
// Use the stream
} // <- This will call the stream's `Dispose` method.

Кроме этого (и упаковки исключение IOException , о котором уже говорилось), Я бы сказал, Это, кажется, нормально.

2
ответ дан 26 июля 2011 в 07:07 Источник Поделиться