可以';无法使XML(反)序列化程序正常工作
本文关键字:程序 序列化 常工作 工作 可以 XML | 更新日期: 2023-09-27 18:14:25
我一直在做自己设定的快速挑战;制作一个通用的XML(反(序列化程序。我在I/O部分遇到了问题。代码如下:
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using UnityEngine;
public static class XML
{
static readonly Dictionary<string, XmlSerializer> PathSerializers = new Dictionary<string, XmlSerializer>();
public static T DeserializeXML<T>(string xmlPath)
{
var serializer = GetSerializer<T>(xmlPath);
var xml = File.ReadAllText(GetFullPath(xmlPath));
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
return (T) serializer.Deserialize(stream);
}
}
public static void SerializeXML<T>(T obj, string xmlPath, bool append)
{
using (var text = new StreamWriter(GetFullPath(xmlPath), append, Encoding.ASCII))
{
GetSerializer<T>(xmlPath).Serialize(text, obj);
}
}
private static XmlSerializer GetSerializer<T>(string relativePath)
{
return PathSerializers.ContainsKey(relativePath) ? PathSerializers[relativePath] : AddSerializer<T>(relativePath);
}
private static string GetFullPath(string relativePath)
{
return Path.Combine(Application.dataPath, relativePath);
}
private static XmlSerializer AddSerializer<T>(string relativePath)
{
if (File.Exists(GetFullPath(relativePath)))
{
File.Create(GetFullPath(relativePath));
}
if (PathSerializers.ContainsKey(relativePath))
{
Debug.Log("Loaded cached serializer");
return GetSerializer<T>(relativePath);
}
var serializer = new XmlSerializer(typeof(T));
PathSerializers.Add(relativePath, serializer);
return serializer;
}
}
这可能是我犯了一些疯狂的新手错误,但我根本看不出来
这些方法是从另一个脚本调用的,并且是在我知道设置正确的类上调用的。
澄清:
如果我序列化然后反序列化相同的数据,我会得到如下错误:
IOException:路径上存在共享冲突C: ''Dev''C#''Projects''XML''Assets''leaderboard.XMLSystem.IO.FileStream.ctor(System.String路径,FileMode模式,FileAccess访问,FileShare共享,Int32缓冲区大小,布尔值匿名,文件选项((位于/Users/builduser/buildslave/mono运行时和classlibs/build/mcs/class/corlib/System.IO/FileStream.cs:320(System.IO.FileStream.ctor(System.String路径,FileMode模式,FileAccess访问,FileShare共享,Int32缓冲区大小((包装带检查的远程调用(System.IO.FileStream:.ctor(字符串,System.IO.FileMode,System.IO.FileAccess,System.IO_FileShare,int(System.IO.File.Create(System.String路径,Int32缓冲区大小((位于/Users/builduser/buildslave/mono运行时和classlibs/build/mcs/class/corlib/System.IO/File.cs:135(System.IO.File.Create(System.String路径((位于/Users/builduser/buildslave/mono运行时和classlibs/build/mcs/class/corlib/System.IO/File.cs:130(XML.AddSerializer[Leaderboard](System.String relativePath((位于Assets/XMLLoader.cs:43(XML.GetSerializer[Leaderboard](System.StringrelativePath((位于Assets/XMLLoader.cs:31(XML.SerializeXML[Leaderboard](.Leaderboard obj,System.StringxmlPath,布尔附加((位于Assets/XMLLoader.cs:25(XMLTest.Start(((位于Assets/XMLTest.cs:14(
我认为这是一个简单的疏忽。如果文件存在,您正在尝试创建该文件!。只要反转条件,它应该是好的:
if (!File.Exists(GetFullPath(relativePath)))
{
File.Create(GetFullPath(relativePath));
}
为了澄清,这是我用来序列化/反序列化xml的方法。
也许经过修改它会对你有所帮助。
/// <summary>
/// Class containing a load and store method to store a datafile as XML format.
/// </summary>
/// <typeparam name="T">The root object containing the data</typeparam>
public class DataFile<T> where T : new()
{
/// <summary>
/// Load the XML from Path
/// </summary>
/// <param name="path">Path to a XML file containing the data for object of type T</param>
/// <returns>An object of type T as represented by the XML. Will return default(T) when the </returns>
public static T Load(string path)
{
if (!File.Exists(path)) return default(T);
var ser = new XmlSerializer(typeof(T));
using (var stream = File.OpenRead(path))
{
var reader = new XmlTextReader(stream);
if (!ser.CanDeserialize(reader))
return default(T); // return null indicating the file can not be loaded
return (T) ser.Deserialize(reader);
}
}
/// <summary>
/// Stores an object of type T as XML into a file
/// </summary>
/// <param name="path">A path to a file which should be written.</param>
/// <param name="data">The object to be written to the given file</param>
public static void Store(string path, T data)
{
var ser = new XmlSerializer(typeof(T));
using (var stream = File.OpenWrite(path))
{
// Clear the file and write new contents.
stream.SetLength(0);
ser.Serialize(stream, data);
}
}
}