文件上传

来源:互联网 发布:买家怎么进入淘宝客 编辑:程序博客网 时间:2024/05/29 18:16

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

文件上传的思路

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

注意事项:

  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