将FileSystemInfo数组保存到文件

7

我正在尝试保存一个FileInfo和DirectoryInfo对象的数组用作日志文件。目标是在某个时间点捕获目录(和子目录)的图像,以便以后进行比较。我目前正在使用这个类来存储信息:

public class myFSInfo
{
    public FileSystemInfo Dir;
    public string RelativePath;
    public string BaseDirectory;
    public myFSInfo(FileSystemInfo dir, string basedir)
    {
        Dir = dir;
        BaseDirectory = basedir;
        RelativePath = Dir.FullName.Substring(basedir.Length + (basedir.Last() == '\\' ? 1 : 2));
    }
    private myFSInfo() { }
    /// <summary>
    /// Copies a FileInfo or DirectoryInfo object to the specified path, creating folders and overwriting if necessary.
    /// </summary>
    /// <param name="path"></param>
    public void CopyTo(string path)
    {
        if (Dir is FileInfo)
        {
            var f = (FileInfo)Dir;
            Directory.CreateDirectory(path.Substring(0,path.LastIndexOf("\\")));
            f.CopyTo(path,true);
        }
        else if (Dir is DirectoryInfo) Directory.CreateDirectory(path);
    }
}

我尝试过使用XML和二进制对我的类进行序列化,但没有成功。我还尝试创建一个新的类,该类不包含实际的FileInfo,而只包含选定的属性:
public class myFSModInfo
{
    public Type Type;
    public string BaseDirectory;
    public string RelativePath;
    public string FullName;
    public DateTime DateModified;
    public DateTime DateCreated;
    public myFSModInfo(FileSystemInfo dir, string basedir)
    {
        Type = dir.GetType();
        BaseDirectory = basedir;
        RelativePath = dir.FullName.Substring(basedir.Length + (basedir.Last() == '\\' ? 1 : 2));
        FullName = dir.FullName;
        DateModified = dir.LastWriteTime;
        DateCreated = dir.CreationTime;
    }
    private myFSModInfo() { }
    /// <summary>
    /// Copies a FileInfo or DirectoryInfo object to the specified path, creating folders and overwriting if necessary.
    /// </summary>
    /// <param name="path"></param>
    public void CopyTo(string path)
    {
        if (Type == typeof(FileInfo))
        {
            Directory.CreateDirectory(path.Substring(0, path.LastIndexOf("\\")));
            File.Copy(FullName,path, true);
        }
        else if (Type == typeof(DirectoryInfo)) Directory.CreateDirectory(path);
    }
    public void Delete() 
    {
        if (Type == typeof(FileInfo)) File.Delete(FullName);
        else if (Type == typeof(DirectoryInfo)) Directory.Delete(FullName);
    }
}

我也没有成功地序列化这个。我可以列出我在尝试中遇到的各种错误,但最好先选择最好的方法。以下是我的序列化代码:

public void SaveLog(string savepath, string dirpath)
    {
        var dirf = new myFSModInfo[1][];
        string[] patharr = {dirpath}; 
        GetFSInfo(patharr, dirf);

        var mySerializer = new System.Xml.Serialization.XmlSerializer(typeof(myFSModInfo[]));
        var myWriter = new StreamWriter(savepath);
        mySerializer.Serialize(myWriter, dirf[0]);
        myWriter.Close();

        /*var bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();   
        FileStream fs = new FileStream(savepath, FileMode.Create, FileAccess.Write);   
        bf.Serialize(fs, dirf[0]);  */
    }

4
认为你只能序列化属性,而不能序列化变量。 - Chuck Savage
你能提供一些更具体的细节,说明你遇到了哪些问题吗? - Octopoid
1
你是否将该类声明为可序列化的?[Serializable] - Sorceri
我已经编辑了您的标题,请查看“问题标题是否应包含“标签”?”,共识是“不应该”。 - John Saunders
谢谢John。Sorceri - 我没有在我发布的代码之外做任何事情。如果将其声明为Serializable可以解决我的问题,你能告诉我语法吗?Octopoid - 我遇到的大多数问题都是由于类没有包含0个参数构造函数而导致序列化器失败。我还遇到了Type被保护变量的问题。如果有特定的路线应该关注,我可以发布确切的错误消息。 - Kalev Maricq
1个回答

5

FileSystemInfo不可序列化,因为它不是简单类型。 FileInfo不可序列化,因为它没有空默认构造函数

因此,如果您想保存该信息,必须使用简单类型构建自己的类,该类包装FileInfo或FileSystemInfo中的信息。

[Serializable]
public class MyFileInfo
{
    public string Name { get; set; }

    public long Length { get; set;}

    /// <summary>
    /// An empty ctor is needed for serialization.
    /// </summary>
    public MyFileInfo(){
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="test.MyFileInfo"/> class.
    /// </summary>
    /// <param name="fileInfo">File info.</param>
    public MyFileInfo(string path)
    {
        FileInfo fileInfo = new FileInfo (path);
        this.Length = fileInfo.Length;
        this.Name = fileInfo.Name;
        // TODO: add and initilize other members
    }
}

用法示例:

List<MyFileInfo> list = new List<MyFileInfo> ();

foreach (string entry in Directory.GetFiles(@"c:\temp"))
{
    list.Add (new MyFileInfo (entry));
}

XmlSerializer xsSubmit = new XmlSerializer(typeof(List<MyFileInfo>));
StringWriter sww = new StringWriter();
XmlWriter writer = XmlWriter.Create(sww);
xsSubmit.Serialize(writer, list);

Console.WriteLine (sww.ToString());

某些访问修饰符可能是错误的。请确保您要序列化的类是公共的。如果它具有复杂属性,则它们也必须具有公共可见类型。如果您想忽略某些属性,则必须使用 [XmlIgnore] 属性。 - devmb
那么为什么你需要那个类型呢?你也可以创建一个名为IsFile的布尔属性作为解决方法! - devmb
我需要将类型编码为字符串吗?保存数组的最佳方法是什么? - Kalev Maricq
那个方法可以行得通。那真的是我需要它的主要原因。虽然我做过其他编程,但C#对我来说是新的。这是保存数据的通用方式吗:创建一个带有所需属性的类,将所有内容转换为简单类型,并进行XML序列化? - Kalev Maricq
没错,MSDN上有一个详细的大部分内容。请参考https://msdn.microsoft.com/en-us/library/182eeyhh%28VS.80%29.aspx。 - devmb
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接