我正在使用Craft.Net.Client库,但是在尝试使用ServerList.SaveTo(字符串文件)方法时出错了:无法在流结束后读取(EndOfStreamException)
ServerList.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using fNbt;
namespace Craft.Net.Client
{
/// <summary>
/// Provides functionality for interacting with
/// the saved vanilla server list.
/// </summary>
public class ServerList
{
public static string ServersDat
{
get
{
return Path.Combine(DotMinecraft.GetDotMinecraftPath(), "servers.dat");
}
}
public ServerList()
{
Servers = new List<Server>();
}
public List<Server> Servers { get; set; }
public void Save()
{
SaveTo(ServersDat);
}
public void SaveTo(string file)
{
var nbt = new NbtFile(file); // ERROR : Unable to read beyond the end of the stream (EndOfStreamException)
nbt.RootTag = new NbtCompound("");
var list = new NbtList("servers", NbtTagType.Compound);
foreach (var server in Servers)
{
var compound = new NbtCompound();
compound.Add(new NbtString("name", server.Name));
compound.Add(new NbtString("ip", server.Ip));
compound.Add(new NbtByte("hideAddress", (byte)(server.HideAddress ? 1 : 0)));
compound.Add(new NbtByte("acceptTextures", (byte)(server.AcceptTextures ? 1 : 0)));
list.Add(compound);
}
nbt.RootTag.Add(list);
nbt.SaveToFile(file, NbtCompression.None);
}
public static ServerList Load()
{
return LoadFrom(ServersDat);
}
public static ServerList LoadFrom(string file)
{
var list = new ServerList();
var nbt = new NbtFile(file);
foreach (NbtCompound server in nbt.RootTag["servers"] as NbtList)
{
var entry = new Server();
if (server.Contains("name"))
entry.Name = server["name"].StringValue;
if (server.Contains("ip"))
entry.Ip = server["ip"].StringValue;
if (server.Contains("hideAddress"))
entry.HideAddress = server["hideAddress"].ByteValue == 1;
if (server.Contains("acceptTextures"))
entry.AcceptTextures = server["acceptTextures"].ByteValue == 1;
list.Servers.Add(entry);
}
return list;
}
public class Server
{
public string Name { get; set; }
public string Ip { get; set; }
public bool HideAddress { get; set; }
public bool AcceptTextures { get; set; }
public override string ToString()
{
return Name;
}
}
}}
我称之为方法的地方:
ServerList.Server server = new ServerList.Server();
server.Name = "x";
server.Ip = "x";
server.HideAddress = true;
server.AcceptTextures = true;
ServerList list = new ServerList();
list.Servers.Add(server);
if (!File.Exists(RuntimeInfo.getMinecraftDir() + @"\servers.dat"))
{
File.Create(RuntimeInfo.getMinecraftDir() + @"\servers.dat");
}
list.SaveTo(RuntimeInfo.getMinecraftDir() + @"\servers.dat");我注意到的一件事是,只有当servers.dat为空时才会收到错误,而如果已经保存了服务器,则不会得到错误。
有谁可以帮我?
提前谢谢你,
编辑:多亏了steveg89,下面的解决方案解决了问题(更新SaveTo方法):
public void SaveTo(string file)
{
NbtFile nbt;
if (File.Exists(RuntimeInfo.getMinecraftDir() + @"\servers.dat"))
{
nbt = new NbtFile();
nbt.SaveToFile(RuntimeInfo.getMinecraftDir() + @"\servers.dat", NbtCompression.None);
}
else
nbt = new NbtFile();
nbt.RootTag = new NbtCompound("");
var list = new NbtList("servers", NbtTagType.Compound);
foreach (var server in Servers)
{
var compound = new NbtCompound();
compound.Add(new NbtString("name", server.Name));
compound.Add(new NbtString("ip", server.Ip));
compound.Add(new NbtByte("hideAddress", (byte)(server.HideAddress ? 1 : 0)));
compound.Add(new NbtByte("acceptTextures", (byte)(server.AcceptTextures ? 1 : 0)));
list.Add(compound);
}
nbt.RootTag.Add(list);
nbt.SaveToFile(file, NbtCompression.None);
}发布于 2013-07-29 20:25:55
我注意到他们的NbtFile构造函数试图从文件中读取。它假设文件的格式已经正确。这意味着你必须创建并保存它。他们的API应该为您处理这个问题,但是没有,所以试试下面这个
if (!File.Exists(RuntimeInfo.getMinecraftDir() + @"\servers.dat"))
{
NbtFile nbt = new NbtFile();
nbt.SaveToFile(RuntimeInfo.getMinecraftDir() + @"\servers.dat", Nbt.Compression.None);
}我认为更明智的方法是纠正SaveTo的ServerList方法。这种方法意味着您不必在代码中检查它,但它确实意味着您将使用您自己的Craft.Net风格。我会这样做:
public void SaveTo(string file)
{
NbtFile nbt;
if( File.Exists( file ) )
{
nbt = new NbtFile(file);
}
else
{
nbt = new NbtFile();
}
nbt.RootTag = new NbtCompound("");
var list = new NbtList("servers", NbtTagType.Compound);
foreach (var server in Servers)
{
var compound = new NbtCompound();
compound.Add(new NbtString("name", server.Name));
compound.Add(new NbtString("ip", server.Ip));
compound.Add(new NbtByte("hideAddress", (byte)(server.HideAddress ? 1 : 0)));
compound.Add(new NbtByte("acceptTextures", (byte)(server.AcceptTextures ? 1 : 0)));
list.Add(compound);
}
nbt.RootTag.Add(list);
nbt.SaveToFile(file, NbtCompression.None);
}https://stackoverflow.com/questions/17933470
复制相似问题