NanoHTTPD 如何将上传的文件保存到 sdcard 文件夹

NanoHTTPD How to save uploaded file to sdcard folder

如何将上传的文件保存到 sdcard 文件夹,目前它存储到 /data/data/cache 文件夹,文件名类似于 "NanoHTTPD-some random number"。

我无法将其复制到 SD 卡中的任何文件夹位置。

我想将文件保存到 sdcard 中前面提到的文件夹位置,其名称与从我的 html 页面上传的原始文件名相同。

各种代码都试过了,但是文件复制总是失败。 1) 无法获得临时文件的正确位置。 2) 没有得到表单发布的原始文件名

这是我的实现。

请帮帮我。

    public class HttpMultimediaServer extends NanoHTTPD {
    private static final String TAG = "HttpMultimediaServer";
    private FileInputStream fileInputStream;

    public HttpMultimediaServer() {
        super(12345);
        this.setTempFileManagerFactory(new ExampleManagerFactory());
    }

    @Override 
    public Response serve(IHTTPSession session) {
        Method method = session.getMethod();
        String uri = session.getUri();

        Log.e("handle", "url>>" + uri);

        if (uri.contains(filesOnly)) {
            isfilesOnly = true;
            uri = "/";
        } else
            isfilesOnly = false;

        uri = uri.replace("%20", " ");

        try {
            uri=new String (uri.getBytes ("iso-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e2) {
            e2.printStackTrace();
        }


        File filePathServer = new File(uri);



        if (method==Method.POST) {

            try {


                Map<String, String> hdrs=session.getHeaders();
                Map<String, String> params=session.getParms();

                Map<String, String> files = new HashMap<String, String>();
                session.parseBody(files);

                Set<String> keys = files.keySet();
                for(String key: keys){
                    String name = key;
                    String loaction = files.get(key);

                    File tempfile = new File(loaction);


                String tempFileName = files.get(loaction).toString();
                File fileToMove = new File(tempFileName); 

    // temp file path returned by NanoHTTPD

                String p =Environment.getExternalStorageDirectory().getPath();
                String newFile = p + "/LICENSE.txt";
                File nf = new File(newFile); // I want to move file here

                if (fileToMove.canWrite()) {
                    boolean success = fileToMove.renameTo(nf);
                    if (success == true) {
                        // LOG to console
                        Log.i("FILE_MOVED_TO", newFile);
                    } else {
                        Log.e("FILE_MOVE_ERROR", tempFileName);
                    }
                } else {
                    Log.e("PERMISSION_ERROR_TEMP_FILE", tempFileName);
                }

                }
                uploadstatus = UPLOAD_SUCESS;


                return new Response("UPLOAD_SUCESS");


            } catch (Exception e) {
                e.printStackTrace();
                uploadstatus = UPLOAD_FAIL;

                return new Response("UPLOAD_FAIL");

            }


        }

    }


    public static void copy(File src, File dst) throws IOException {
        InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst);

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
    }

    public static void copyFile(File src, File dst) throws IOException
    {
        FileChannel inChannel = new FileInputStream(src).getChannel();
        FileChannel outChannel = new FileOutputStream(dst).getChannel();
        try
        {
            inChannel.transferTo(0, inChannel.size(), outChannel);
        }
        finally
        {
            if (inChannel != null)
                inChannel.close();
            if (outChannel != null)
                outChannel.close();
        }
    }





    private Response getFullResponse(String mimeType,String filePath) throws FileNotFoundException {
    //        cleanupStreams();
        fileInputStream = new FileInputStream(filePath);
        return new Response(Response.Status.OK, mimeType, fileInputStream);
    }

    private Response getPartialResponse(String mimeType, String rangeHeader,String filePath) throws IOException {
        File file = new File(filePath);
        String rangeValue = rangeHeader.trim().substring("bytes=".length());
        long fileLength = file.length();
        long start, end;
        if (rangeValue.startsWith("-")) {
            end = fileLength - 1;
            start = fileLength - 1
                    - Long.parseLong(rangeValue.substring("-".length()));
        } else {
            String[] range = rangeValue.split("-");
            start = Long.parseLong(range[0]);
            end = range.length > 1 ? Long.parseLong(range[1])
                    : fileLength - 1;
        }
        if (end > fileLength - 1) {
            end = fileLength - 1;
        }
        if (start <= end) {
            long contentLength = end - start + 1;
    //            cleanupStreams();
            fileInputStream = new FileInputStream(file);
                //noinspection ResultOfMethodCallIgnored
            fileInputStream.skip(start);
            Response response = new Response(Response.Status.PARTIAL_CONTENT, mimeType, fileInputStream);
            response.addHeader("Content-Length", contentLength + "");
            response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
            response.addHeader("Content-Type", mimeType);
            return response;
        } else {
            return new Response(Response.Status.RANGE_NOT_SATISFIABLE, "text/html", rangeHeader);
        }
    }
    int UPLOAD_SUCESS = 1;
    int UPLOAD_FAIL = -1;
    int UPLOAD_NO = 0;
    int uploadstatus;
    boolean isfilesOnly;
    String filesOnly = "?filesOnly=1";
    ArrayList<CLocalFile> list;
    StringBuilder sb;

    public void walkdir(File dir) {

        File listFile[] = dir.listFiles();
        if (listFile != null) {
            for (int i = 0; i < listFile.length; i++) {
                // checking if it is a directory
                if (listFile[i].isDirectory()) {
                    if (isfilesOnly)
                        walkdir(listFile[i]);
                    else {
                        CLocalFile f = new CLocalFile();
                        f.setName(listFile[i].getName());
                        f.setData(listFile[i].getAbsolutePath());
                        f.setSize("Folder");
                        list.add(f);
                        continue;
                    }
                }
                    // checking the file extension if it is a file
                String fileName = listFile[i].getName();

                String extension = "";

                int e = fileName.lastIndexOf('.');
                if (e > 0) {
                    extension = fileName.substring(e + 1);
                }
                if (!isfilesOnly
                        || CollabUtility.video_pattern.contains(extension
                                .toLowerCase(Locale.ENGLISH))
                        || CollabUtility.document_pattern.contains(extension
                                .toLowerCase(Locale.ENGLISH))
                        || CollabUtility.audio_pattern.contains(extension
                                .toLowerCase(Locale.ENGLISH))) {
                    CLocalFile f = new CLocalFile();
                    f.setName(fileName);
                    String mb = "Bytes";
                    double size = listFile[i].length();
                    if (size > 1024) {
                        size = size / 1024;
                        mb = "KB";
                    }
                    if (size > 1024) {
                        size = size / 1024;
                        mb = "MB";
                    }
                    if (size > 1024) {
                        size = size / 1024;
                        mb = "GB";
                    }
                    size = Math.floor(size * 100 + 0.5) / 100;
                    f.setSize(size + " " + mb);
                    f.setData(listFile[i].getAbsolutePath());
                    list.add(f);
                }
            }
        }
    }

    void listofMedia(File file) {
        list = new ArrayList<CLocalFile>();
        walkdir(file);
        // now create the html page
        String style = "<style>" + "html {background-color:#eeeeee;} "
                + "body { background-color:#FFFFFF; "
                + "font-family:Tahoma,Arial,Helvetica,sans-serif; "
                + "font-size:18x; " + "border:3px " + "groove #006600; "
                + "padding:15px; } " + "</style>";

        String script = "<script language='javascript'>"
                + "function clickit(state) {"
                + "if(state==true){document.getElementById('filesonly').checked="
                + "! document.getElementById('filesonly').checked}"
                + "if ( document.getElementById('filesonly').checked == false ){"
                + "var l=window.location.href;" + "l=l.replace('" + filesOnly
                + "', '');" + "window.location=l;" + "}"
                + "else{var l=window.location.href;"
                + "window.location=String.concat(l,'" + filesOnly + "')" + "}"
                + "}</script>";
        Log.d("check", script);

        sb = new StringBuilder();
        sb.append("<html>");
        sb.append("<head>");
        sb.append("<title>Files from device</title>");
        sb.append(style);
            // sb.append("<script language='javascript'>"
            // + "function clickit() {"
            // + "if ( document.getElementById('filesonly').checked == false ){"
            // + "var l=window.location.href;" + "l=l.replace('" + filesOnly
            // + "', '');" + "window.location=l;" + "}"
            // + "else{var l=window.location.href;"
            // + "window.location=String.concat(l,'" + filesOnly + "')" + "}"
            // + "}</script>");
        sb.append(script);
        sb.append("</head>");

        sb.append("<body alink=\"blue\" vlink=\"blue\">");

        Log.d("check", sb.toString());

            // if(true)
            // return;
            // form upload
        sb.append("<h3>File Upload:</h3>");
        sb.append("Select a file to upload: <br/>");
        sb.append("<form action=\"\" method=\"post\"  enctype=\"multipart/form-data\">");
        sb.append("<input type=\"file\" name=\"uploadfile\" size=\"50\" />");
        sb.append("<input type=\"submit\" value=\"Upload File\" />");
        sb.append("</form>");

        if (uploadstatus == UPLOAD_FAIL)
            sb.append("<h3><font color='red'>The upload was failed</font></h3>");
        else if (uploadstatus == UPLOAD_SUCESS)
            sb.append("<h3><font color='red'>The upload was successfull</font></h3>");

        // if files are there or not
        if (list != null && list.size() != 0) {
            sb.append("<h3>The following files are hosted live from ");
            if (!isfilesOnly)
                sb.append("<font color='blue'>" + file.getName()
                        + "</font> folder of ");
            sb.append("the device</h3>");
        } else {
            sb.append("<h3>Couldn't find any file from <font color='blue'>"
                    + file.getName() + "</font> folder of the device</h3>");
        }

        // checkbox
        if (isfilesOnly)
            sb.append("<input type=\"checkbox\" onchange='clickit(false);' checked='true' id=\"filesonly\" />"
                    + "<asd onclick='clickit(true);' style=\"cursor:default;\">"
                    + "Show only relevant Files (Audio, Video and Documents)</asd>");
        else
            sb.append("<input type=\"checkbox\" onchange='clickit(false);' id=\"filesonly\" />"
                    + "<asd onclick='clickit(true);' style=\"cursor:default;\">"
                    + "Show only relevant Files (Audio, Video and Documents)</asd>");

            // table of files
        sb.append("<table cellpadding='5px' align=''>");

           // showing path URLs if not only files
        if (!isfilesOnly) {
            ArrayList<File> href = new ArrayList<File>();
            File parent = new File(file.getPath());
            while (parent != null) {
                href.add(parent);
                    // pointing to the next parent
                parent = parent.getParentFile();
            }

            sb.append("<tr>");
            sb.append("<td colspan=2><b>");
            sb.append("<a href='" + file.getParent() + "'>");
            sb.append("UP");
            sb.append("</a>");

                // printing the whole structure
            String path = "";
            for (int i = href.size() - 2; i >= 0; --i) {
                path = href.get(i).getPath();
                if (isfilesOnly)
                    path += filesOnly;
                sb.append("  =>  <a href='" + path + "'>");
                sb.append(href.get(i).getName());
                sb.append("</a>");
            }
            sb.append("</b></td>");
            sb.append("</tr>");
        }

        sb.append("<tr>");

        sb.append("<td>");
        sb.append("<b>File Name</b>");
        sb.append("</td>");

        sb.append("<td>");
        sb.append("<b>Size / Type</b>");
        sb.append("</td>");

        sb.append("<tr>");

            // sorting the list
        Collections.sort(list);

            // showing the list of files
        for (CLocalFile f : list) {
            String data = f.getData();
            if (isfilesOnly)
                data += filesOnly;
            sb.append("<tr>");

            sb.append("<td>");
            sb.append("<a href='" + data + "'>");
            sb.append(f.getName());
            sb.append("</a>");
            sb.append("</td>");

            sb.append("<td align=\"right\">");
            sb.append(f.getSize());
            sb.append("</td>");

            sb.append("</tr>");
        }
        sb.append("</table>");
        sb.append("</body>");
        sb.append("</html>");
    }



    private static class ExampleManagerFactory implements TempFileManagerFactory {
        @Override
        public TempFileManager create() {
            return new ExampleManager();
        }
    }

    private static class ExampleManager implements TempFileManager {
        private final String tmpdir;
        private final List<TempFile> tempFiles;

        private ExampleManager() {
            tmpdir = System.getProperty("java.io.tmpdir");
    //             tmpdir = System.getProperty("/sdcard");

            tempFiles = new ArrayList<TempFile>();
        }

        @Override
        public TempFile createTempFile() throws Exception {
            DefaultTempFile tempFile = new DefaultTempFile(tmpdir);
            tempFiles.add(tempFile);
            System.out.println("Created tempFile: " + tempFile.getName());
            return tempFile;
        }

        @Override
        public void clear() {
            if (!tempFiles.isEmpty()) {
                System.out.println("Cleaning up:");
            }
            for (TempFile file : tempFiles) {
                try {
                    System.out.println("   "+file.getName());
                    file.delete();
                } catch (Exception ignored) {}
            }
            tempFiles.clear();
        }
    }

}

如果您使用的是 NanoHTTPD r.2.1.0,请尝试这些代码:

@Override
public Response serve(IHTTPSession session) {
    Map<String, String> headers = session.getHeaders();
    Map<String, String> parms = session.getParms();
    Method method = session.getMethod();
    String uri = session.getUri();
    Map<String, String> files = new HashMap<>();

    if (Method.POST.equals(method) || Method.PUT.equals(method)) {
        try {
            session.parseBody(files);
        } catch (IOException ioe) {
            return getResponse("Internal Error IO Exception: " + ioe.getMessage());
        } catch (ResponseException re) {
            return new Response(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
        }
    }

    if ("/uploadfile".equalsIgnoreCase(uri)) {
        String filename = parms.get("filename");
        String tmpFilePath = files.get("filename");
        if (null == filename || null == tmpFilePath) {
            // Response for invalid parameters
        }
        File dst = new File(mCurrentDir, filename);
        if (dst.exists()) {
            // Response for confirm to overwrite
        }
        File src = new File(tmpFilePath);
        try {
            InputStream in = new FileInputStream(src);
            OutputStream out = new FileOutputStream(dst);
            byte[] buf = new byte[65536];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        } catch (IOException ioe) {
            // Response for failed
        }
        // Response for success
    }

    // Others...
}

为了在单个输入文件中上传多个文件,例如:

<input type="file" name="filename" multiple>

我修改了 NanoHTTPD.java 中的 decodeMultipartData() 方法:

        private void decodeMultipartData(String boundary, ByteBuffer fbuf, BufferedReader in, Map<String, String> parms,
                                     Map<String, String> files) throws ResponseException {
        try {
            int[] bpositions = getBoundaryPositions(fbuf, boundary.getBytes());
            int boundarycount = 1;
            String mpline = in.readLine();
            while (mpline != null) {
                if (!mpline.contains(boundary)) {
                    throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but next chunk does not start with boundary. Usage: GET /example/file.html");
                }
                boundarycount++;
                Map<String, String> item = new HashMap<String, String>();
                mpline = in.readLine();
                while (mpline != null && mpline.trim().length() > 0) {
                    int p = mpline.indexOf(':');
                    if (p != -1) {
                        item.put(mpline.substring(0, p).trim().toLowerCase(Locale.US), mpline.substring(p + 1).trim());
                    }
                    mpline = in.readLine();
                }
                if (mpline != null) {
                    String contentDisposition = item.get("content-disposition");
                    if (contentDisposition == null) {
                        throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but no content-disposition info found. Usage: GET /example/file.html");
                    }
                    StringTokenizer st = new StringTokenizer(contentDisposition, ";");
                    Map<String, String> disposition = new HashMap<String, String>();
                    while (st.hasMoreTokens()) {
                        String token = st.nextToken().trim();
                        int p = token.indexOf('=');
                        if (p != -1) {
                            disposition.put(token.substring(0, p).trim().toLowerCase(Locale.US), token.substring(p + 1).trim());
                        }
                    }
                    String pname = disposition.get("name");
                    pname = pname.substring(1, pname.length() - 1);

                    String value = "";
                    if (item.get("content-type") == null) {
                        while (mpline != null && !mpline.contains(boundary)) {
                            mpline = in.readLine();
                            if (mpline != null) {
                                int d = mpline.indexOf(boundary);
                                if (d == -1) {
                                    value += mpline;
                                } else {
                                    value += mpline.substring(0, d - 2);
                                }
                            }
                        }
                    } else {
                        if (boundarycount > bpositions.length) {
                            throw new ResponseException(Response.Status.INTERNAL_ERROR, "Error processing request");
                        }
                        int offset = stripMultipartHeaders(fbuf, bpositions[boundarycount - 2]);
                        String path = saveTmpFile(fbuf, offset, bpositions[boundarycount - 1] - offset - 4);
                        files.put(pname, path);
                        value = disposition.get("filename");
                        value = value.substring(1, value.length() - 1);
                        do {
                            mpline = in.readLine();
                        } while (mpline != null && !mpline.contains(boundary));
                    }
                    parms.put(pname, value);
                }
            }
        } catch (IOException ioe) {
            throw new ResponseException(Response.Status.INTERNAL_ERROR, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage(), ioe);
        }
    }

待定:

        private void decodeMultipartData(String boundary, ByteBuffer fbuf, BufferedReader in, Map<String, String> parms,
                                     Map<String, String> files) throws ResponseException {
        try {
            String pname_0 = "";
            String pname_1 = "";
            int pcount = 1;

            int[] bpositions = getBoundaryPositions(fbuf, boundary.getBytes());
            int boundarycount = 1;
            String mpline = in.readLine();
            while (mpline != null) {
                if (!mpline.contains(boundary)) {
                    throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but next chunk does not start with boundary. Usage: GET /example/file.html");
                }
                boundarycount++;
                Map<String, String> item = new HashMap<String, String>();
                mpline = in.readLine();
                while (mpline != null && mpline.trim().length() > 0) {
                    int p = mpline.indexOf(':');
                    if (p != -1) {
                        item.put(mpline.substring(0, p).trim().toLowerCase(Locale.US), mpline.substring(p + 1).trim());
                    }
                    mpline = in.readLine();
                }
                if (mpline != null) {
                    String contentDisposition = item.get("content-disposition");
                    if (contentDisposition == null) {
                        throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but no content-disposition info found. Usage: GET /example/file.html");
                    }
                    StringTokenizer st = new StringTokenizer(contentDisposition, ";");
                    Map<String, String> disposition = new HashMap<String, String>();
                    while (st.hasMoreTokens()) {
                        String token = st.nextToken().trim();
                        int p = token.indexOf('=');
                        if (p != -1) {
                            disposition.put(token.substring(0, p).trim().toLowerCase(Locale.US), token.substring(p + 1).trim());
                        }
                    }
                    String pname = disposition.get("name");
                    pname = pname.substring(1, pname.length() - 1);

                    if (pname.contentEquals(pname_0)) {
                        pname_1 = pname + String.valueOf(pcount);
                        pcount++;
                    } else {
                        pname_0 = pname;
                        pname_1 = pname;
                    }

                    String value = "";
                    if (item.get("content-type") == null) {
                        while (mpline != null && !mpline.contains(boundary)) {
                            mpline = in.readLine();
                            if (mpline != null) {
                                int d = mpline.indexOf(boundary);
                                if (d == -1) {
                                    value += mpline;
                                } else {
                                    value += mpline.substring(0, d - 2);
                                }
                            }
                        }
                    } else {
                        if (boundarycount > bpositions.length) {
                            throw new ResponseException(Response.Status.INTERNAL_ERROR, "Error processing request");
                        }
                        int offset = stripMultipartHeaders(fbuf, bpositions[boundarycount - 2]);
                        String path = saveTmpFile(fbuf, offset, bpositions[boundarycount - 1] - offset - 4);
                        files.put(pname_1, path);
                        value = disposition.get("filename");
                        value = value.substring(1, value.length() - 1);
                        do {
                            mpline = in.readLine();
                        } while (mpline != null && !mpline.contains(boundary));
                    }
                    parms.put(pname_1, value);
                }
            }
        } catch (IOException ioe) {
            throw new ResponseException(Response.Status.INTERNAL_ERROR, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage(), ioe);
        }
    }

希望这对您有所帮助,抱歉我的英语不好..:-)

这是我的工作代码:

public Response serve(IHTTPSession session) {
    Map<String, String> headers = session.getHeaders();
    Map<String, String> parms = session.getParms();
    Method method = session.getMethod();
    String uri = session.getUri();
    Map<String, String> files = new HashMap<>();

    if (Method.POST.equals(method) || Method.PUT.equals(method)) {
        try {
            session.parseBody(files);
        } catch (IOException ioe) {
            return getResponse("Internal Error IO Exception: " + ioe.getMessage());
        } catch (ResponseException re) {
            return new Response(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
        }
    }

    uri = uri.trim().replace(File.separatorChar, '/');
    if (uri.indexOf('?') >= 0) {
        uri = uri.substring(0, uri.indexOf('?'));
    }

    // Other implementation goes here...

    if ("/uploadfiles".equalsIgnoreCase(uri)) {
        String filename, tmpFilePath;
        File src, dst;
        for (Map.Entry entry : parms.entrySet()) {
            if (entry.getKey().toString().substring(0, 8).equalsIgnoreCase("filename")) {
                filename = entry.getValue().toString();
                tmpFilePath = files.get(entry.getKey().toString());
                dst = new File(mCurrentDir, filename);
                if (dst.exists()) {
                    return getResponse("Internal Error: File already exist");
                }
                src = new File(tmpFilePath);
                if (! copyFile(src, dst)) {
                    return getResponse("Internal Error: Uploading failed");
                }
            }
        }
        return getResponse("Success");
    }

    return getResponse("Error 404: File not found");
}

private boolean deleteFile(File target) {
    if (target.isDirectory()) {
        for (File child : target.listFiles()) {
            if (! deleteFile(child)) {
                return false;
            }
        }
    }
    return target.delete();
}

private boolean copyFile(File source, File target) {
    if (source.isDirectory()) {
        if (! target.exists()) {
            if (! target.mkdir()) {
                return false;
            }
        }
        String[] children = source.list();
        for (int i = 0; i < source.listFiles().length; i++) {
            if (! copyFile(new File(source, children[i]), new File(target, children[i]))) {
                return false;
            }
        }
    } else {
        try {
            InputStream in = new FileInputStream(source);
            OutputStream out = new FileOutputStream(target);

            byte[] buf = new byte[65536];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        } catch (IOException ioe) {
            return false;
        }
    }
    return true;
}

private Response getResponse(String message) {
    return createResponse(Response.Status.OK, MIME_PLAINTEXT, message);
}

// Announce that the file server accepts partial content requests
private Response createResponse(Response.Status status, String mimeType, String message) {
    Response res = new Response(status, mimeType, message);
    res.addHeader("Accept-Ranges", "bytes");
    return res;
}

允许上传多个文件:

<input type="file" name="filename" multiple>

2.2.1 分支中存在同样的问题。按照相同的逻辑,我通过几行代码更改修复了相同的功能。

在函数开头添加一个计数器pcount:

private void decodeMultipartFormData(String boundary, String encoding, ByteBuffer fbuf, Map<String, String> parms, Map<String, String> files) throws ResponseException {
   int pcount = 1;
   try {

如果文件名不为空,则使用计数器更新键名:

while (matcher.find()) {
     String key = matcher.group(1);
     if ("name".equalsIgnoreCase(key)) {
         part_name = matcher.group(2);
     } else if ("filename".equalsIgnoreCase(key)) {
         file_name = matcher.group(2);
         // add these two line to support multiple
         // files uploaded using the same field Id
         if (!file_name.isEmpty()) {
            if (pcount > 0)
               part_name = part_name + String.valueOf(pcount++);
            else
               pcount++;
         }
     }
}

可能会迟到,但只是为了像我这样的迟到者。

之前解释过,客户端使用okhttp上传文件就像下面的代码:

RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
    //sourceFile is a File as you know
            .addFormDataPart("image_file_1", "logo-square1.png", RequestBody.create(MediaType.parse("image/png"), sourceFile))
            .build();

    Request request = new Request.Builder()
            .url(url)
            .post(requestBody)
            .build();
    Response response = client.newCall(request).execute();

下面的代码就是你想要的

@Override
public Response serve(IHTTPSession session) {

    Method method = session.getMethod();
    // ▼ 1、parse post body ▼
    Map<String, String> files = new HashMap<>();
    if (Method.POST.equals(method) || Method.PUT.equals(method)) {
        try {
            session.parseBody(files);
        } catch (IOException ioe) {
            return getResponse("Internal Error IO Exception: " + ioe.getMessage());
        } catch (ResponseException re) {
            return newFixedLengthResponse(re.getStatus(), MIME_PLAINTEXT, re.getMessage());
        }
    }
    //after the body parsed, by default nanoHTTPD will save the file to cache and put it into params( "image_file_1" as key and the value is "logo-square1.png");
    //files key is just like "image_file_1", and the value is nanoHTTPD's template file path in cache
    // ▲ 1、parse post body ▲


    // ▼ 2、copy file to target path xiaoyee ▼
    Map<String, String> params = session.getParms();
    for (Map.Entry<String, String> entry : params.entrySet()) {
        final String paramsKey = entry.getKey();
        if (paramsKey.contains("image_file_1")) {
            final String tmpFilePath = files.get(paramsKey);
            final String fileName = paramsKey;
            final File tmpFile = new File(tmpFilePath);
            final File targetFile = new File(mCurrentDir + fileName);
            LogUtil.log("copy file now, source file path: %s,target file path:%s", tmpFile.getAbsoluteFile(), targetFile.getAbsoluteFile());
            //a copy file method just what you like
            copyFile(tmpFile, targetFile);

            //maybe you should put the follow code out
            return getResponse("Success");
        }
    }
    // ▲ 2、copy file to target path xiaoyee ▲

    return getResponse("Error 404: File not found");
}