读取 json 文件并根据文件数据下载文件
本文关键字:文件 数据 下载 json 读取 | 更新日期: 2023-09-27 18:31:32
有很多事情要解释,所以如果我没有足够彻底地解释我正在寻找的东西,我提前道歉,如果您需要我澄清任何事情,请问,我会尽力而为。
所以我正在用 C# 制作一个 minecraft 启动器,我已经到了我需要下载资产的部分,在 assets 文件夹中有两个文件夹索引和对象,现在我将专注于索引文件夹。我已经有启动器从 http://s3.amazonaws.com/Minecraft.Download/indexes/1.7.10.json 下载 1.7.10.json(我建议下载文件,以便您可以查看整个内容,无需帐户即可下载它。当我尝试阅读 1.7.10.json 时,问题就来了,我已经尝试了我能想到的所有方法,我也尝试寻找在线读取文件的方法,但似乎都不起作用。话虽如此,我能够使用此代码读取文件并对 .json 文件进行一些编辑。
public void SevenTenAssets()
{
string root = @"C:'SamplePack1";
string Index = (root + "''.minecraft''assets''indexes''");
using (StreamReader r = new StreamReader(Index + "1.7.10.json"))
{
string json = r.ReadToEnd();
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);
DataTable dataTable = dataSet.Tables["objects"];
foreach (DataRow row in dataTable.Rows)
{
Console.WriteLine(row["hash"]);
}
}
}
但是我不相信我能够分发编辑的文件,而不是从mojang拥有的服务器分发。所以这种方法真的可以用。
但这不是唯一的问题。假设我能够读取未经编辑的文件,我仍然需要取出每个哈希并将其插入此 url http://resources.download.minecraft.net/(哈希的前 2 个十六进制字母)/(整个哈希)以下载与所述哈希相关的文件。希望这个例子能更清楚地说明:
在 1.7.10.json 文件中,代码如下所示。
{"objects": {
"realms/lang/de_DE.lang": {
"hash": "729b2c09d5c588787b23127eeda2730f9c039194",
"size": 7784
},
"realms/lang/cy_GB.lang": {
"hash": "7b52463b2df4685d2d82c5d257fd5ec79843d618",
"size": 7688
},
想象一下文件中总共有 686 个哈希,但无论如何我需要取出每个哈希,例如第一个 729b2c09d5c588787b23127eeda2730f9c039194
然后复制每个哈希的前两个字符,并创建一个以前两个字符命名的文件夹,因此在此哈希中它将是一个名为 72 的文件夹。在前面提到的对象文件夹中创建文件夹后,它需要转到前面提到的链接(我无法在此再次发布它,因为我的声誉少于 10 个,并且不能发布超过 2 个链接,但它是具有 resource.download.minecraft 的链接而不是 s3.amazonaws 链接)
将与所述哈希关联的文件下载到名为 72 的文件夹中。您很可能会看到 url 的"(哈希的前 2 个十六进制字母)/(整个哈希)"部分,这是因为要下载与哈希关联的文件,它需要获取 has 的前两个字符,在这种情况下它是 72,然后添加一个/then 和整个哈希将下载文件。您可能还认为我可以将链接放在代码中而不必读取 json,但我实际上需要让它读取 .json 文件,因为它需要与多个版本的 .json 一起使用(IE:1.7.10.json、1.8.json 等)。提前感谢您的帮助。
更新
包含自定义的仅限运行时属性名称的 JSON 对象,例如更新后的链接中显示的 JSON:
{ "objects": { "realms/lang/de_DE.lang": { "hash": "729b2c09d5c588787b23127eeda2730f9c039194", "size": 7784 }, "realms/lang/cy_GB.lang": { "hash": "7b52463b2df4685d2d82c5d257fd5ec79843d618", "size": 7688 } } }
可以反序列化为字典。 请参阅反序列化字典。 因此,可以使用以下数据模型:
public class HashAndSize
{
public string hash { get; set; }
public long size { get; set; }
}
public class ObjectTable
{
public Dictionary<string, HashAndSize> objects { get; set; }
}
并用 json.net 反序列化,如下所示:
var url = @"http://s3.amazonaws.com/Minecraft.Download/indexes/1.7.10.json";
ObjectTable root;
using (var wc = new System.Net.WebClient())
using (var stream = wc.OpenRead(url))
using (var textReader = new StreamReader(stream))
using (var reader = new JsonTextReader(textReader))
{
root = JsonSerializer.CreateDefault().Deserialize<ObjectTable>(reader);
}
"realms/lang/cy_GB.lang"
字符串将成为字典键。
原始答案
我将当前显示在您的链接 http://s3.amazonaws.com/Minecraft.Download/versions/1.7.10/1.7.10.json JSON 上传到 http://json2csharp.com/,它为我自动生成了以下类:
public class Natives
{
public string linux { get; set; }
public string windows { get; set; }
public string osx { get; set; }
}
public class Extract
{
public List<string> exclude { get; set; }
}
public class Os
{
public string name { get; set; }
}
public class Rule
{
public string action { get; set; }
public Os os { get; set; }
}
public class Library
{
public string name { get; set; }
public Natives natives { get; set; }
public Extract extract { get; set; }
public List<Rule> rules { get; set; }
}
public class RootObject
{
public string id { get; set; }
public string time { get; set; }
public string releaseTime { get; set; }
public string type { get; set; }
public string minecraftArguments { get; set; }
public int minimumLauncherVersion { get; set; }
public string assets { get; set; }
public List<Library> libraries { get; set; }
public string mainClass { get; set; }
}
这样做后,我能够使用以下代码下载和反序列化 JSON:
var url = @"http://s3.amazonaws.com/Minecraft.Download/versions/1.7.10/1.7.10.json";
RootObject root;
using (var wc = new System.Net.WebClient())
using (var stream = wc.OpenRead(url))
using (var textReader = new StreamReader(stream))
using (var reader = new JsonTextReader(textReader))
{
root = JsonSerializer.CreateDefault().Deserialize<RootObject>(reader);
}