2015-02-26 84 views
1

如何將上傳的文件保存到SD卡文件夾中,目前它存儲到/ data/data/cache文件夾,其文件名類似「NanoHTTPD-some random number」。NanoHTTPD如何將上傳的文件保存到SD卡文件夾

我無法將其複製到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(); 
     } 
    } 

} 
+0

的moveTo不會爲源工作是什麼和目的地在不同的'分區'上。更好地使用copyfile()。 – greenapps

+0

對不起。我改名爲。 – greenapps

+0

在那裏做過重命名也失敗了 –

回答

2

如果使用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... 
} 
+0

雖然,你的答案晚了,但答案沒有少。我無法得到原來的文件名,你需要從params中得到。我的代碼:String origFileName = params.get(key); \t \t \t \t \t \t String srcFilepath = files.get(key); \t \t \t srcfile = new File(srcFilepath); \t \t \t dstfile = new File(filePathServer +「/」+ origFileName); \t \t \t \t \t \t如果 \t \t \t \t dstfile.createNewFile()(dstfile.exists()!); \t \t \t \t \t \t CollabUtility.copyFile(srcfile,dstfile); –

1

爲了上傳多個文件中像一個單一的輸入文件:

<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); 
     } 
    } 

希望這有助於爲我的英語不好對不起.. :-)

+0

您能否詳細說明一下,您更改後的代碼可能會有所幫助? –

+0

如果您使用一個輸入類型文件但有多個標記,並且提交它們時,NanoHTTPD會成功解析所有文件,但名稱(在上例中使用「文件名」)對於所有保存在映射中的文件始終相似變量作爲一個關鍵字,這個值首先被後面的值覆蓋,因爲它們使用相似的關鍵字。 – ZulNs

+0

在你的代碼中,你永遠不會得到實際的名字而不是鍵'String name = key',你應該使用'String name = parms.get(key)'來取回實際的文件名。 – ZulNs

1

這是我的工作代碼:

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; 
} 
1

要允許多個文件上傳:

<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++; 
     } 
    } 
} 
0

也許晚了,但只是對於像我這樣的後來者來說。

以前解釋的那樣,客戶端使用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"); 
}