首页 > 解决方案 > 使用 Nanohttpd 进行文件传输

问题描述

我想制作一个非常简单的服务器,可以在 Java Desktop 和 Android 上使用,因此我可能会使用小型库NanoHttpd。如果有人有更好的选择,请随时推荐。

因此,服务器主要用于从许多自定义 WiFi 设备接收文件,并将一些设置推送给它们。但是,由于文件可能很大(200Mb+)并且传输速度很慢,我需要能够从服务器(Android/PC)访问此传输的进度。

NanoHttpd 有没有办法获得这个进展?到目前为止,我似乎理解在调用“serve()”方法之前完全收到了请求,并且下载完成了。

标签: javaandroidhttpservernanohttpd

解决方案


非常老的问题,但我想它会帮助任何人到达这里。

如果您正在谈论nanohttpd正在服务的文件的进度,您可以很容易地做到这一点。将此类复制粘贴到您的代码中

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

public class ProgressInputStream extends InputStream {

    private InputStream in;
    private int length, sumRead;
    private java.util.List<Listener> listeners;
    private double percent;

    public ProgressInputStream(InputStream inputStream, int length) {
        this.in = inputStream;
        listeners = new ArrayList<>();
        sumRead = 0;
        this.length = length;
    }


    @Override
    public int read(byte[] b) throws IOException {
        int readCount = in.read(b);
        evaluatePercent(readCount);
        return readCount;
    }


    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int readCount = in.read(b, off, len);
        evaluatePercent(readCount);
        return readCount;
    }

    @Override
    public long skip(long n) throws IOException {
        long skip = in.skip(n);
        evaluatePercent(skip);
        return skip;
    }

    @Override
    public int read() throws IOException {
        int read = in.read();
        if (read != -1) {
            evaluatePercent(1);
        }
        return read;
    }

    public ProgressInputStream addListener(Listener listener) {
        this.listeners.add(listener);
        return this;
    }

    private void evaluatePercent(long readCount) {
        if (readCount != -1) {
            sumRead += readCount;
            percent = sumRead * 1.0 / length;
        }
        notifyListener();
    }

    private void notifyListener() {
        for (Listener listener : listeners) {
            listener.process(percent);
        }
    }
}

进度界面

public interface ProgressListener {
    void process(double percent);
}

现在您可以通过在方法nanohttpd中编写此代码来了解所服务的任何文件的进度serve

@Override
public NanoHTTPD.Response server(NanoHTTPD.IHTTPSession session) throws FileNotFoundException {
    if(session.getUri().equals("/file_to_be_served")) {
        File file = new File("file_to_be_served");
        FileInputStream fis = new FileInputStream(file);
        ProgressInputStream pis = new ProgressInputStream(fis, (int) file.length());
        pis.addListener(mProgressListener);
        return newChunkedResponse(NanoHTTPD.Response.Status.OK, "mime_type_of_the_file", pis);
    }
}

file_to_be_served将是文件的路径,mime_type_of_the_file应该是mimetype.

现在您可以根据需要修改此样板代码。希望对大家有所帮助。


推荐阅读