我正在尝试使用 XmlSerializer 将 XML 文件写入 azure 文件共享,但我的文件始终与我设置的 MaxSize 一样大。
我有一个 Azure 函数,它调用以下函数,将导入的 RowSet 数据写入 XML 文件,然后将该 XML 上传到 Azure 文件存储。 XML 文件通常约为 100-250 MiB 大,这意味着我想使用 Azure.Storage.Files.Shares 命名空间中包含的 OpenWrite 函数。
但是为了使用 OpenWrite,您需要在 ShareFileOpenWriteOptions 中指定 MaxSize,但这就是我的麻烦开始的地方。创建的文件的大小始终与 MaxSize 相同,即使它是空 XML。因此,如果我将 MaxSize 的值设置为“1024 * 1024 * 4”,我的序列化 XML 文件将始终显示为 4MiB,如果我将 MaxSize 设置为“1024 * 1024 * 500”,则文件将始终显示为 500MiB。
public void WriteXmlToFile(<MyRowSetType> rs, string filePath, string fileName)
{
try
{
ShareFileClient fileClient = _shareClient.GetDirectoryClient(filePath).GetFileClient(fileName);
ShareFileOpenWriteOptions uploadOptions = new ShareFileOpenWriteOptions
{
MaxSize = 1024 * 1024 * 100
};
using (var stream = fileClient.OpenWrite(true, 0, uploadOptions))
{
var serializer = new XmlSerializer(typeof(<MyRowSetType>));
serializer.Serialize(stream, rs);
}
}
catch (Exception ex)
{
_logger.LogError($"Error writing XML to Azure File Storage, FileName: {fileName}, FilePath: {filePath}, Exception: {ex}");
throw;
}
}
我不知道我是否误解了MaxSize的作用,我认为它设置了最大可能的文件大小,而不是实际大小。如果我首先将(在本例中为空)XML 加载到内存中,我会得到正确的文件大小(170 字节),但同样,我不想在上传大型 XML 文件之前将其加载到内存中。
var serializer = new XmlSerializer(typeof(<MyRowSetType>));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, rs);
var xml = writer.ToString();
XmlDocument doc2 = new XmlDocument();
doc2.LoadXml(xml);
var len = doc2.OuterXml.Length;
ShareFileOpenWriteOptions uploadOptions = new ShareFileOpenWriteOptions
{
MaxSize = len
};
using (var stream = fileClient.OpenWrite(true, 0, uploadOptions))
{
stream.Write(Encoding.UTF8.GetBytes(doc2.OuterXml), 0, len);
}
}
所以我正在寻求帮助,如何序列化 XML 文件而不先将它们加载到内存中。
也许我只是把事情复杂化了?
要解决此问题并创建具有正确大小的 XML 文件而不先将其加载到内存中,您可以采用不同的方法。您可以将数据序列化到临时流(如 MemoryStream),然后将内容复制到 Azure 文件流,而不是依赖 MaxSize 属性。
但是如果您只想写入 XML 文件,您可以使用条件:
public void WriteXmlToFile(<MyRowSetType> rs, string filePath, string fileName, long maxSize)
{
try
{
ShareFileClient fileClient = _shareClient.GetDirectoryClient(filePath).GetFileClient(fileName);
using (var tempMemoryStream = new MemoryStream())
{
var serializer = new XmlSerializer(typeof(<MyRowSetType>));
serializer.Serialize(tempMemoryStream, rs);
tempMemoryStream.Seek(0, SeekOrigin.Begin);
if (tempMemoryStream.Length > maxSize)
{
// Handle the case where the data exceeds MaxSize
throw new InvalidOperationException("Data size exceeds the specified MaxSize.");
}
ShareFileOpenWriteOptions uploadOptions = new ShareFileOpenWriteOptions
{
MaxSize = tempMemoryStream.Length
};
using (var fileStream = fileClient.OpenWrite(true, 0, uploadOptions))
{
tempMemoryStream.CopyTo(fileStream);
}
}
}
catch (Exception ex)
{
throw;
}
}