根据文件数据读取json个文件并下载文件

Read json file and download files based on file data

这将有很多事情需要解释,所以如果我没有足够彻底地解释我正在寻找的东西,我提前道歉,如果你需要我澄清任何事情,请尽管问,我会尽力而为.

所以我正在用 C# 制作一个 minecraft 启动器,我已经到了需要下载资产的部分,在资产文件夹中有两个文件夹索引和对象,现在我将专注于索引文件夹。我已经有了从 http://s3.amazonaws.com/Minecraft.Download/indexes/1.7.10.json 下载 1.7.10.json 的启动器(我建议您下载该文件,这样您就可以查看整个文件,下载它不需要帐户。)问题来了我正在尝试阅读 1.7.10.json 我已经尝试了所有我能想到的方法,我也尝试寻找在线阅读文件的方法,但其中 none 似乎有效。这就是说我能够使用这段代码读取文件并对 .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 的文件夹。在之前提到的对象文件夹中创建文件夹后,它需要去之前提到的 link (我不能再 post 因为我的声望少于 10 并且不能 post 超过 2 link,但是 link 有 resource.download.minecraft 而不是 s3.amazonaws link)

将与所述哈希关联的文件下载到名为 72 的文件夹中。 您很可能会看到 url 的“(散列的前 2 个十六进制字母)/(整个散列)”部分,这是因为要下载与散列关联的文件,它需要获取 has 的前两个字符,在本例中是 72,然后添加一个 / 然后是将下载文件的整个哈希值。您可能还认为我可以将 link 放入代码中而不必读取 json 但实际上我需要让它读取 .json 文件,因为它需要工作具有多个版本的 .json(IE:1.7.10.json、1.8.json,等等)。 提前感谢您的帮助。

更新

JSON 包含自定义 run-time-only 属性 名称的对象,例如 your updated link:

中显示的 JSON
{
  "objects": {
    "realms/lang/de_DE.lang": {
      "hash": "729b2c09d5c588787b23127eeda2730f9c039194",
      "size": 7784
    },
    "realms/lang/cy_GB.lang": {
      "hash": "7b52463b2df4685d2d82c5d257fd5ec79843d618",
      "size": 7688
    }
  }
}

可以反序列化为字典。参见 Deserialize a Dictionary。因此可以使用以下数据模型:

public class HashAndSize
{
    public string hash { get; set; }
    public long size { get; set; }
}

public class ObjectTable
{
    public Dictionary<string, HashAndSize> objects { get; set; }
}

并用反序列化如下:

        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" 字符串成为字典键。

原答案

我上传了 JSON 当前显示在您的 link http://s3.amazonaws.com/Minecraft.Download/versions/1.7.10/1.7.10.json to 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);
        }