提问人:Kalev Maricq 提问时间:6/9/2015 最后编辑:Kalev Maricq 更新时间:6/10/2015 访问量:927
将 FileSystemInfo 数组保存到文件
Saving FileSystemInfo Array to File
问:
我正在尝试保存 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和Binary序列化我的类,但没有运气。我还尝试创建一个不包含实际 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]); */
}
答:
5赞
devmb
6/9/2015
#1
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());
评论
0赞
Kalev Maricq
6/10/2015
谢谢ec8or。在阅读您的回复后,我意识到我错误地重复了第一个代码块,而不是发布我的第二次尝试。我现在已经解决了这个问题。这与您的建议一致,但我收到此错误:“System.InvalidOperationException:System.RuntimeType 由于其保护级别而无法访问。只能处理公共类型。
0赞
devmb
6/10/2015
某些访问修饰符可能是错误的。确保要序列化的类是公共类。如果它具有复杂的属性,它们也必须具有 publiv 可见类型。如果要忽略某些属性,则必须使用 [XmlIgnore] -Attribute。
0赞
Kalev Maricq
6/10/2015
您可以在上面的第二个代码块中看到我的类。我想我把两者都公开了。我不想忽略任何属性,因为我只在此类中包含了我需要的属性。在我的第一堂课中,我包含了一个 FileSystemInfo 对象,该对象具有我可以忽略的属性,但 XMLserializer 不喜欢 FileInfo。我添加了 Serializeable 标签,但仍然没有运气。知道问题是什么吗?
0赞
devmb
6/11/2015
这里的问题是.它不可序列化,因为.它是一种内部 CLR 类型。此外,它不是一个简单的类型。明白了?Type
System.RuntimeType is inaccessible due to its protection level.
0赞
devmb
6/11/2015
那么,为什么需要这种类型呢?您还可以创建一个名为 IsFile 的 bool 属性作为 workarround!?
评论