Android-将图片上传到服务器的最佳做法

时间:2019-06-24 20:47:59

标签: android

我有一些代码将字符串字节发送到服务器,然后在mvc c#中,我将这些字符串字节转换为原始字节,然后将字节保存到文件中。这很好用,但是当我在HttpURLConnection内发送4个字符串字节图像的问题时,mvc服务器返回并显示File Not Found Exception。

所以我发现当我发送大图像时,它会因这种异常而失败,而当我发送的图像小于3080000字节时,它将发送图像并将其保存到服务器。

因此,现在我决定向用户显示一条消息,显示有关文件限制的对话框,这样做很好吗?

这是我的代码:

客户

try {

            if (imgS!=null && imgS.size()>0) {
                for (int i = 0; i < imgS.size(); i++) {

                    if(i == 0){
                        image1 = Base64.encodeToString(imgS.get(i).bytes, Base64.DEFAULT);
                    }
                    if(i == 1){
                        image2 = Base64.encodeToString(imgS.get(i).bytes, Base64.DEFAULT);
                    }
                    if(i == 2){
                        image3 = Base64.encodeToString(imgS.get(i).bytes, Base64.DEFAULT);
                    }
                    if(i == 3){
                        image4 = Base64.encodeToString(imgS.get(i).bytes, Base64.DEFAULT);
                    }
                }
            }


            if (!isDelivered) {
                deliveredId = 2;
            }


            if (params[0] != null && (params[0].equals("0.00") || !params[0].equals(""))) {
                priceTmp = Double.valueOf(params[0]);
            }

            if (params[6] != null && (params[6].equals("0.00") || !params[6].equals(""))) {
                postageTmp = Double.valueOf(params[6]);
            }
            String responseText = "";

            SharedPreferences preferences = getActivity().getSharedPreferences(PREFERENCE, Context.MODE_PRIVATE);

            String json = String.format("{\"p_u_id\": \"%s\",\"price\": \"%.2f\"," +
                            "\"title\": \"%s\"" +
                            ",\"description\": \"%s\",\"category\": \"%d\",\"tags\": \"%s\"" +
                            ",\"image1\": \"%s\",\"image2\": \"%s\",\"image3\": \"%s\",\"image4\": \"%s\"" +
                            ",\"postcode\": \"%s\",\"postage\": \"%.2f\",\"isDelivered\": \"%d\"}",
                    preferences.getString("userId", "0"),
                    priceTmp,
                    params[1],
                    params[2],
                    selectedCategory,
                    params[4],
                    image1,
                    image2,
                    "",
                    "",
                    params[5],
                    postageTmp,
                    deliveredId
            );

            long b = image1.getBytes().length + image2.getBytes().length +image3.getBytes().length + image4.getBytes().length;
            if(b > 3080000){


                return "FileLimit";

            }else{


                URL url = new URL("http://xxx/Home/xxxx");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(10000);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Content-Type", "application/json");      // have tried without this
                conn.setRequestProperty("Content-Length", json.getBytes().length + "");
                conn.setDoOutput(true);

                OutputStream os = conn.getOutputStream();
                os.write(json.getBytes("UTF-8"));
                os.close();

                conn.connect();

                InputStream is = conn.getInputStream();
                //here we read and print the response send by server; assuming that response type is text/html (MIME Type)
                StringBuilder sb = new StringBuilder();
                int ch;
                //-1: end of stream
                while ((ch = is.read()) != -1) {
                    sb.append((char) ch);
                }
                responseText = sb.toString();

                conn.disconnect();
                JSONObject obj = new JSONObject(responseText);
                pid = obj.getInt("id");
                serverImage1 = obj.getString("image1");
                serverImage2 = obj.getString("image2");


                json = String.format("{\"p_id\": \"%d\",\"image1\": \"%s\"," +
                                "\"image2\": \"%s\",\"p_u_id\": \"%s\"}",
                        pid,
                        image3,
                        image4,
                        preferences.getString("userId", "0")

                );

                url = new URL("http://xxx/Home/xxxx");
                conn = (HttpURLConnection) url.openConnection();
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(10000);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Content-Type", "application/json");      // have tried without this
                conn.setRequestProperty("Content-Length", json.getBytes().length + "");
                conn.setDoOutput(true);

                os = conn.getOutputStream();
                os.write(json.getBytes("UTF-8"));
                os.close();

                conn.connect();

                is = conn.getInputStream();
                //here we read and print the response send by server; assuming that response type is text/html (MIME Type)
                sb = new StringBuilder();
                ch = 0;
                //-1: end of stream
                while ((ch = is.read()) != -1) {
                    sb.append((char) ch);
                }

                responseText = sb.toString();
                return responseText;
            }




        } catch (Exception e) {
            int i = 0;
        }

我在这里所做的是将前两个图像发送到服务器,然后在发送前两个图像之后发送下两个图像。这很有趣,因为即使我发送两个较大的图像,服务器也会再次出现异常。

那么向用户显示有关文件限制的消息是否很好?

shpock n Ebay等其他应用允许多文件上传时又如何工作?

我尝试使用一些Android库,但是并不安全。

想知道一种在不向用户显示文件限制的情况下最多发送四个文件的方法,而直接发送这四个图像。

MVC

if(image.Length > 0)
        {

            byte[] bytes = Convert.FromBase64String(image);

            if (!System.IO.Directory.Exists(Server.MapPath("~/App_Data/products/" + uid)))
            {
                System.IO.Directory.CreateDirectory(Server.MapPath("~/App_Data/products/") + uid);
            }


            if (!System.IO.Directory.Exists(Server.MapPath("~/App_Data/products/" + uid + "/" + pid)))
            {
                System.IO.Directory.CreateDirectory(Server.MapPath("~/App_Data/products/") + uid + "/" + pid);
            }
            string path = Path.Combine(Server.MapPath("~/App_Data/products/" + uid + "/" + pid), guid + "" + ".jpg");

            System.IO.File.WriteAllBytes(path, bytes);
        }

2 个答案:

答案 0 :(得分:0)

拥有映像后,可以将其上传到Firestore或Amazon S3等云数据库,然后发送链接而不是字节!

答案 1 :(得分:0)

向用户显示文件限制是个好主意吗?是的。比弹出错误要好。

为什么它不能用于大于3MB的图像?那么,如果您查看Microsoft文档,您的Convert.FromBase64String方法会将数据放入一个无符号的8位整数数组中。一个无符号的int最大值为429万,因此,因为您已经对base64进行了编码,所以图像实际上要大33%,因为在进行base64编码时它的比例为4:3。

Convert.FromBase64String(String) Method

Base64 Padding file size increases

因此,您不能上传大于3MB的内容。

其他公司如何进行多文件上传?那么,他们只是为每个文件异步调用相同的文件上传终结点。因此,如果您发送4个文件,它将同时发出4个请求,这些请求将慢慢上传图像(通常您可以看到每个文件的进度条指示)。