gpt4 book ai didi

c# - protobuf-net 不支持指定的方法

转载 作者:行者123 更新时间:2023-12-04 05:27:33 25 4
gpt4 key购买 nike

我最近决定使用 protobuf-net序列化大型纯文本数据文件,我的应用程序使用它来查看解析纯文本数据是否有任何性能提升。

数据类:

[ProtoContract]
public class ClimateFile : BaseModel
{
#region Properties
[ProtoMember(1)]
public double Latitude { get { return GetValue(() => Latitude); } private set { SetValue(() => Latitude, value); } }

[ProtoMember(2)]
public double Longitude { get { return GetValue(() => Longitude); } private set { SetValue(() => Longitude, value); } }

[ProtoMember(3)]
public string Notes { get { return GetValue(() => Notes); } set { SetValue(() => Notes, value); } }

[ProtoMember(4)]
public DateTime MinDate { get { return GetValue(() => MinDate); } private set { SetValue(() => MinDate, value); } }

[ProtoMember(5)]
public DateTime MaxDate { get { return GetValue(() => MaxDate); } private set { SetValue(() => MaxDate, value); } }

[ProtoMember(6)]
public List<ClimateDailyData> DailyData { get { return GetValue(() => DailyData); } private set { SetValue(() => DailyData, value); } }
#endregion

#region Method
public static ClimateFile Load(string filePath)
{
try
{
var ext = Path.GetExtension(filePath).ToUpper();
if (ext == ".P51")
return new ClimateFile(filePath);
else if (ext == ".P51X")
{
ClimateFile climateFile;
using (var file = File.OpenRead(filePath))
{
climateFile = Serializer.Deserialize<ClimateFile>(file);
}
return climateFile;
}
}
catch (Exception e)
{
throw new InvalidDataException(String.Format("The file \"{0}\" could not be opened, {1}", filePath, ExceptionUtilities.JoinExceptionMessages(e)));
}

throw new ArgumentException("filePath was not a .P51 or .P51X file.");
}

public void LoadP51File(string filePath)
{
List<string[]> lines = GetFileLines(filePath);
Latitude = double.Parse(lines[0][0]);
Longitude = double.Parse(lines[0][1]);
for (int i = 2; i < lines[0].Length; ++i)
Notes += String.Format("{0} ", lines[0][i]);
MinDate = GetDate(lines[2][0]);
MaxDate = GetDate(lines[lines.Count - 1][0]);

// Parse daily data
lines.RemoveRange(0, 2);
var dailyData = lines.Select(row => new ClimateDailyData()
{
DataDate = GetDate(row[0]),
MaxTemperature = double.Parse(row[2]),
MinTemperature = double.Parse(row[3]),
Rainfall = double.Parse(row[4]),
Evaporation = double.Parse(row[5]),
SolarRadiation = double.Parse(row[6])
}).ToList();
DailyData = dailyData;
}

public void SaveP51XFile(string filePath)
{
using (var file = File.Create(filePath))
{
Serializer.Serialize<ClimateFile>(file, this);
}
}

public List<string[]> GetFileLines(string filePath)
{
var rows = new List<string[]>();
var cells = new List<string>();
var cell = new StringBuilder();
using (var fs = new BufferedStream(File.OpenRead(filePath)))
{
int buffer;
while ((buffer = fs.ReadByte()) != -1)
{
char nextChar = (char)buffer;

if (nextChar >= '!') // If the character is a non-whitespace printable character
{
cell.Append(nextChar);
continue;
}

if (nextChar == ' ' || nextChar == '\t')
{
if (cell.Length > 0)
{
cells.Add(cell.ToString());
cell.Clear();
}
continue;
}

if (nextChar == '\r' || nextChar == '\n')
{
if (cell.Length > 0)
{
cells.Add(cell.ToString());
cell.Clear();
}
if (cells.Count > 0)
{
rows.Add(cells.ToArray());
cells.Clear();
}
continue;
}
throw new InvalidDataException("The climate file contains unknown characters.");
}

if (cell.Length > 0)
cells.Add(cell.ToString());
if (cells.Count > 0)
rows.Add(cells.ToArray());
}
return rows;
}

public DateTime GetDate(string date)
{
return DateTime.ParseExact(date, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
}

public override void Dispose()
{
if (Disposed)
return;
if (DailyData != null)
foreach (ClimateDailyData dailyData in DailyData)
dailyData.Dispose();
base.Dispose();
}
#endregion

#region Initialization
public ClimateFile()
{
}

public ClimateFile(string filePath)
{
LoadP51File(filePath);
}
#endregion
}

采集数据类:
    [ProtoContract]
public class ClimateDailyData : BaseModel
{
[ProtoMember(1)]
public DateTime DataDate { get { return GetValue(() => DataDate); } set { SetValue(() => DataDate, value); } }

[ProtoMember(2)]
public int JulianDay { get { return DataDate.DayOfYear; } }

[ProtoMember(3)]
public double MaxTemperature { get { return GetValue(() => MaxTemperature); } set { SetValue(() => MaxTemperature, value); } }

[ProtoMember(4)]
public double MinTemperature { get { return GetValue(() => MinTemperature); } set { SetValue(() => MinTemperature, value); } }

[ProtoMember(5)]
public double Rainfall { get { return GetValue(() => Rainfall); } set { SetValue(() => Rainfall, value); } }

[ProtoMember(6)]
public double Evaporation { get { return GetValue(() => Evaporation); } set { SetValue(() => Evaporation, value); } }

[ProtoMember(7)]
public double SolarRadiation { get { return GetValue(() => SolarRadiation); } set { SetValue(() => SolarRadiation, value); } }
}

序列化命令:
public ICommand ImportP51
{
get
{
return new RelayCommand(delegate
{
OpenFileDialog openDialogue = new OpenFileDialog()
{
AddExtension = true,
CheckPathExists = true,
CheckFileExists = true,
DefaultExt = ".p51",
Filter = "Climate Files|*.p51",
InitialDirectory = DataPath,
Multiselect = false,
Title = "Select a File to Open"
};

if ((bool)openDialogue.ShowDialog())
{
string filePath = String.Empty;
try
{
filePath = openDialogue.FileName;
var climate = new Climate();
climate.FilePath = filePath;
var savePath = String.Format("{0}\\{1}.p51x", ClimateDataPath, Path.GetFileNameWithoutExtension(filePath));
climate.FileData.SaveP51XFile(savePath);
}
catch (Exception e)
{
MessageBox.Show(String.Format("The file \"{0}\" could not be opened, {1}", filePath, ExceptionUtilities.JoinExceptionMessages(e)), "Invalid File");
}
}
});
}
}

执行 ImportP51时,我收到异常“不支持指定的方法”,我正在使用 2012 年 12 月 10 日发布的 protobuf-net V2 r594,如果我不能让它工作,我正在考虑尝试使用以前的版本之一用这个版本。有人可以告诉我我做错了什么吗?

最佳答案

我试图重建代码的工作版本(因为我没有你的 BaseModel ),我通过使用自动实现的属性并为列表添加一个初始化程序( DailyData )并明确引用来自谷歌代码的 r594。我得到的唯一错误是:

Cannot apply changes to property ClimateDailyData.JulianDay



这是有道理的,因为它不能正确地将数据反序列化为只读属性,所以我从那个属性中删除了序列化标记:
// [ProtoMember(2)] removed - serialized implicitly via DataData
public int JulianDay { get { return DataDate.DayOfYear; } }

之后它工作得很好。因为我没有你的命令框架,所以我有:
static class Program
{
static void Main()
{
var climateFile = new ClimateFile();
climateFile.InitSomeDataForSerialization();

climateFile.SaveP51XFile("foo.P51X");
var clone = ClimateFile.Load("foo.P51X");
}
}

在哪里 InitSomeDataForSerialization只是设置一些值(因为他们有私有(private) setter ,我不能在 Main 中这样做):
public void InitSomeDataForSerialization()
{
Longitude = 10; Latitude = 4; Notes = "Test";

DailyData.Add(
new ClimateDailyData { DataDate = DateTime.Today, MinTemperature = 12, MaxTemperature = 35}
);
}

而且......它有效。

凭直觉,我检查了如果您引用“CoreOnly”而不是“Full”会发生什么,但随后拒绝编译,因为 Serializer.Serialize<T>Serializer.Deserialize<T>不存在。

我很乐意提供帮助,但据我所知,没有任何问题。

接下来我建议的事情:
  • 显示此异常中发生的情况的完整堆栈跟踪,包括任何内部异常(请参阅下面的修复)
  • 请查看正是 您在 594 zip 中引用了哪个文件(查看“What Files Do I Need.txt”,但我猜对您来说正确的是“Full/net30/...”;nuget 包配置了最合适的文件自动)
  • 请展示一个完全可重现的示例,即我可以按 F5 并查看确切的异常(我必须更改示例中的代码才能编译,这意味着我不再测试相同的东西)

  • 修复正确的异常包装:
    catch (Exception e)
    {
    throw new InvalidDataException(String.Format("The file \"{0}\" could not be opened", filePath), e);
    }

    关于c# - protobuf-net 不支持指定的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13021778/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com