文件上传

在项目的开发中。我们经常会遇到文件上传,在此,对文件上传进行一个梳理

文件上传的思路

在实现文件上传的时候,我们可以以文件来上传
也可以以流的形式上传

注意事项:

  1. android 系统分给每个app的内存较低,我们要想法进行缩小上传的文件体积
  2. 上传图片的时候,需要考虑图片的旋转角度(血泪史)

在上传前我们需要做的是压缩图片,生成临时图片

  /**
     * 只有图片,需要压缩
     */
    private String[] getScaleFiles(String[] filePaths) {

        ArrayList<String> list = new ArrayList<>();
        // 创建一个临时的路径
        String imgUploadFilePath = PathUtil.getDiskCacheDir(GlobalContext.getContext(), "temp").getAbsolutePath();

        FileUtil.createNewFolder(imgUploadFilePath);


        try {
            for (String filePath : filePaths) {

                if (FileUtil.isFileExists(filePath)) {

                    if (filePath.endsWith(".jpg") || filePath.endsWith(".png")) {
                        //判断为图片后,开始压缩大计。 主体原则为压缩后的图片,宽高不超过屏幕宽高
                        Bitmap scaleBitmap = BitmapUtil.getBitmapByPath(filePath, SCREEN_WIDTH, SCREEN_HEIGHT);
                        if (scaleBitmap != null) {
                            LogUtil.d("%s", "scaleBitmap img width " + scaleBitmap.getWidth() + " height " + scaleBitmap.getHeight());
                            //旋转为正常方向 并 对图片进行压缩处理
                            String path = getScaleImageFilePath(BitmapUtil.reviewPicRotate(scaleBitmap, filePath), imgUploadFilePath, filePath.hashCode() + ".jpg");
                            list.add(path);
                            //回收bitmap
                            if (scaleBitmap != null && !scaleBitmap.isRecycled()) {
                                LogUtil.d("recycle... %s", path);
                                scaleBitmap.recycle();
                                scaleBitmap = null;
                            }

                        } else {
                            //这种情况发生概率极低,需要手速
                            LogUtil.e("%s", "impossible  file not exists  " + filePath);
                        }
                    } else {
                        //这个理论上是视频。直接丢里面。丢啊丢啊丢手绢
                        list.add(filePath);
                    }

                } else {
                    //如果用户在选择完图片,到了上传界面,还未点上传,但去sdcard下把图片删了,就会走这里
                    LogUtil.e("%s", "skip file not exists   " + filePath);
                }

            }
        } catch (OutOfMemoryError e) {
            LogUtil.e(e.getMessage());
        }


        return CollectionUtil.listToArray(list);


    }


    /**
     * 这里会把图片处理。取屏幕 宽or高 做最长边,等比缩小
     *
     * @param mBitmap
     */
    private String getScaleImageFilePath(Bitmap mBitmap, String imgUploadFilePath, String fileName) {
        if (mBitmap == null) {
            LogUtil.w("getScaleImageFilePath bitmap is null");
            ErrorUtil.report(GMNetRequest.class, "getScaleImageFilePath is null");
            return "";
        }

        LogUtil.d("%s", "scale path " + imgUploadFilePath + File.separator + fileName);

        File f = new File(imgUploadFilePath + File.separator + fileName);
        try {
            if (f.exists()) {
                if (f.isDirectory()) {
                    //是目录那就是用户恶意创建的,防止下面崩溃,删掉
                    f.delete();
                } else {
                    LogUtil.d("%s", "has exists  " + fileName);
                    //如果图片已经处理过,就直接用了。不用再处理
                    return f.getAbsolutePath();
                }
            }
            f.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //取img宽高
        int imgWidth = mBitmap.getWidth();
        int imgHeight = mBitmap.getHeight();
        //求出 高 和 宽 的比
        float scale = (float) imgHeight / imgWidth;
        //取最长边
        int max = imgWidth > imgHeight ? imgWidth : imgHeight;

        if (max == imgWidth && imgWidth > SCREEN_WIDTH) {
            //如果最长边是 宽,并且 宽 大于 屏幕宽度,就要处理
            Float floatValue = Float.valueOf(SCREEN_WIDTH * scale);
            int scaledheight = floatValue.intValue();
            mBitmap = resizeImage(mBitmap, SCREEN_WIDTH, scaledheight);
        } else if (max == imgHeight && imgHeight > SCREEN_HEIGHT) {
            Float floatValue = Float.valueOf(SCREEN_HEIGHT / scale);
            int scaledwidth = floatValue.intValue();
            mBitmap = resizeImage(mBitmap, scaledwidth, SCREEN_HEIGHT);
        }
        if (mBitmap == null) {
            return "";
        }
        LogUtil.i("%s", "after img width " + mBitmap.getWidth() + " mBitmap " + mBitmap.getHeight());
        mBitmap.compress(Bitmap.CompressFormat.JPEG, 70, fOut);
        try {
            fOut.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


        return f.getAbsolutePath();
    }



直接以图片上传

使用httpClient框架来上传

以流的形式上传

在上面我们已经生成了一个临时的文件夹 里面包含了图片,我们需要的是将里面的所有图片生成流并上传
注意–上传的图片需要有 boundary 分隔符

private byte[] createByteData(String jsonData, String boundary, String[] filePaths) throws IOException {

        StringBuilder js = new StringBuilder();
        js.append(jsonData);
        byte[] jsbyte = js.toString().getBytes("utf-8");

        StringBuilder bound = new StringBuilder();
        bound.append(boundary);
        byte[] boundaryByte = bound.toString().getBytes("utf-8");


        ByteArrayOutputStream dataBao = new ByteArrayOutputStream();
        //上传文件规则是 json + 分隔符+ 文件 + 分隔符 + 文件。。。
        dataBao.write(jsbyte);

        for (String path : filePaths) {

            LogUtil.d("upload file path %s ", path);

            byte[] fileByte = readStream(path);
            dataBao.write(boundaryByte);
            dataBao.write(fileByte);
        }


        return dataBao.toByteArray();

    }


    private byte[] readStream(String filePath) throws IOException {
        FileInputStream fs = new FileInputStream(filePath);
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while (-1 != (len = fs.read(buffer))) {
            outStream.write(buffer, 0, len);
        }
        outStream.close();
        fs.close();
        return outStream.toByteArray();
    }

上面我们得到了文件的流–此时我们可以将流上传即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值