Skip to content

下载文件


1.制作

在官方源代码中有案例

可以在mindustry.net.BeControl里找到

import static mindustry.Vars.*;

/** Handles control of bleeding edge builds. */
public class BeControl{
    private void download(String furl, Fi dest, Intc length, Floatc progressor, Boolp canceled, Runnable done, Cons<Throwable> error){
        mainExecutor.submit(() -> {
            try{
                HttpURLConnection con = (HttpURLConnection)new URL(furl).openConnection();
                BufferedInputStream in = new BufferedInputStream(con.getInputStream());
                OutputStream out = dest.write(false, 4096);

                byte[] data = new byte[4096];
                long size = con.getContentLength();
                long counter = 0;
                length.get((int)size);
                int x;
                while((x = in.read(data, 0, data.length)) >= 0 && !canceled.get()){
                    counter += x;
                    progressor.get((float)counter / (float)size);
                    out.write(data, 0, x);
                }
                out.close();
                in.close();
                if(!canceled.get()) done.run();
            }catch(Throwable e){
                error.get(e);
            }
        });
    }
}
但作者的源代码中使用的是 private 我们无法在模组中引用,但没有关系,我们可以试试直接复制。
public void download(String furl, Fi dest, Intc length, Floatc progressor, Boolp canceled, Runnable done, Cons<Throwable> error) {
    mainExecutor.submit(() -> {
        try {
            HttpURLConnection con = (HttpURLConnection) new URL(furl).openConnection();
            BufferedInputStream in = new BufferedInputStream(con.getInputStream());
            OutputStream out = dest.write(false, 4096);

            byte[] data = new byte[4096];
            long size = con.getContentLength();
            long counter = 0;
            length.get((int) size);
            int x;
            while ((x = in.read(data, 0, data.length)) >= 0 && !canceled.get()) {
                counter += x;
                progressor.get((float) counter / (float) size);
                out.write(data, 0, x);
            }
            out.close();
            in.close();
            if (!canceled.get()) done.run();
        } catch (Throwable e) {
            error.get(e);
        }
    });
}
好的方面是用的代码中没有和类绑定的变量,可以轻松复制。
(所以官方为什么要私人化呢?)

2.使用

  • furl:下载文件的网址
  • dest:下载到的路径
  • length:文件长度
  • progressor:下载进度
  • canceled:寸止 取消下载
  • done:下载完成后运行的代码

有亿点多,但霉逝,很多都是可以直接套模板的

boolean[] cancel = {false};
float[] progress = {0};
int[] length = {0};
Fi file = "保存路径"
String updateUrl = "下载文件网址";

BaseDialog dialogdown = new BaseDialog("@be.updating");
download(updateUrl, file, i -> length[0] = i, v -> progress[0] = v, () -> cancel[0], () -> {
//这里写下载完成后运行的代码
}, ed -> {
    dialogdown.hide();
    ui.showException(ed);
});

dialogdown.cont.add(new Bar(() -> length[0] == 0 ? Core.bundle.get("be.updating") : (int)(progress[0] * length[0]) / 1024/ 1024 + "/" + length[0]/1024/1024 + " MB", () -> Pal.accent, () -> progress[0])).width(400f).height(70f);
dialogdown.buttons.button("@cancel", Icon.cancel, () -> {
    cancel[0] = true;
    dialogdown.hide();
}).size(210f, 64f);
dialogdown.setFillParent(false);
dialogdown.show();
大概效果:

当然,你可以使用这种方法来实现更新模组,只不过这不在本章的教程中,可以自行探索。

注意!
下载的文件会缓存在 file 变量写的目录下,如果下载失败文件仍会留存,即使下载成功也仍然,请配合文件删除使用。