使用IO流来实现文件的上传以及前端上传视频组件

1、后端上传

//使用缓存字节流和字节数组来最快的写入视频流

 private String uploadFile(FileInfo fileInfo, String filePath) {
        //filePath = filePath.replaceAll("/", "\\\\\\\\");
        //文件上传项
        String filename = fileInfo.getFileName();  //获得上传文件名称
        //判断文件夹是否存在,不存在则新建
        File file = new File(filePath + filename);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try {
            //使用缓冲字节流来上传文件
            BufferedInputStream bis = new BufferedInputStream(fileInfo.getInputStream());
            //文件存储位置
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath + filename));
            //使用字节数组来加快写视频数据
            byte[] bytes = new byte[2048];
            int len;
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, len);
            }
            bis.close();
            bos.close();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        //返回url地址
        return filePath + filename;
    }

//自己创建的文件对象

package com.inpor.mc.util.ftp;

import java.io.InputStream;
import java.io.Serializable;

/**
 * Created by lijunqi  on 2015/6/4.
 * 上传的文件信息
 */
public class FileInfo implements Serializable {
    private String fileName;//上传文件的名称

    private String contentType;//上传文件的类型

    private Long fileSize;//上传文件输入流

    private String parentPath;//存储文件父目录

    private InputStream inputStream;//上传文件输入流

    private String filePath; //文件路径

    private byte[] datas;//数据

    private Long ftpId;

    private boolean isJdbc = false;

    public FileInfo() {
    }

    /**
     * 构建fileInfo
     */
    public FileInfo(String fileName, String contentType, String parentPath, InputStream inputStream) {
        this.fileName = fileName;
        this.contentType = contentType;
        this.parentPath = parentPath;
        this.inputStream = inputStream;
    }

    /**
     * 构建fileInfo
     */
    public FileInfo(String fileName, String contentType, InputStream inputStream) {
        this.fileName = fileName;
        this.contentType = contentType;
        this.inputStream = inputStream;
    }

    /**
     * 构建fileInfo
     */
    public FileInfo(String fileName, String contentType, Long fileSize, String parentPath, InputStream inputStream) {
        this.fileName = fileName;
        this.contentType = contentType;
        this.fileSize = fileSize;
        this.parentPath = parentPath;
        this.inputStream = inputStream;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public Long getFileSize() {
        return fileSize;
    }

    public void setFileSize(Long fileSize) {
        this.fileSize = fileSize;
    }

    public String getParentPath() {
        return parentPath;
    }

    public void setParentPath(String parentPath) {
        this.parentPath = parentPath;
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public byte[] getDatas() {
        return datas;
    }

    public void setDatas(byte[] datas) {
        this.datas = datas;
    }

    public Long getFtpId() {
        return ftpId;
    }

    public void setFtpId(Long ftpId) {
        this.ftpId = ftpId;
    }

    public boolean isJdbc() {
        return isJdbc;
    }

    public void setJdbc(boolean jdbc) {
        isJdbc = jdbc;
    }

    public FileInfo cloneThis() throws CloneNotSupportedException {
        FileInfo cloneInfo = new FileInfo();

        cloneInfo.setFileName(this.fileName);
        cloneInfo.setContentType(this.contentType);
        cloneInfo.setFileSize(this.fileSize);
        cloneInfo.setParentPath(this.parentPath);
        cloneInfo.setInputStream(this.inputStream);
        cloneInfo.setFilePath(this.filePath);
        cloneInfo.setDatas(this.datas);
        cloneInfo.setFtpId(this.ftpId);
        cloneInfo.setJdbc(this.isJdbc);

        return cloneInfo;
    }

}

2、前端上传组件

2.1、第一个组件kendoUI的使用

function generateUpload() {
    var uploadTimestamp = $("#upload-timestamp").val();
    var uploadIndex = $("#upload-index").val();
    var uploadDeptId = $("#upload-deptId").val();
    var uploadSaveUrl = getBackCtx() + "/studio/myresc/uploadResource?timestamp=" + uploadTimestamp + "&index=" + uploadIndex + "&deptId=" + uploadDeptId;
    var uploadRemoveUrl = getBackCtx() + "/studio/myresc/removeUploadResc?type=0&timestamp=" + uploadTimestamp + "&index=" + uploadIndex + "&deptId=" + uploadDeptId;
    var uploadDiv = $("#videos-upload .form-control");
    uploadDiv.html('<input type="file" name="videos" id="videos" />');
    $("#videos").kendoUpload({
        async: {
            saveUrl: uploadSaveUrl,
            removeUrl: uploadRemoveUrl,
            autoUpload: true
        },
        complete: onComplete,
        cancel: onCancel,
        remove: onRemove,
        showFileList: true,
        success: function (e) {
            var operation = e.operation;
            var responseData = e.response;
            if (responseData != undefined && responseData.error != undefined) {
                showBubble("文件" + responseData.error);
                isUploadSuccess = false;
                return;
            }

            isUploadSuccess = true;

            $.each(e.files, function (index, value) {
                var name = value.name;
                if (operation == 'upload') {
                    showBubble("文件" + "【" + name + "】" + "上传成功" + "!");
                } else {
                    showBubble("文件" + "【" + name + "】" + "移除成功" + "!");
                }
            });
        },
        multiple: true,
        error: onError,
        upload: onUpload,
        select: onSelect,
        progress: onProgress,
        localization: {
            uploadSelectedFiles: "上传",
            cancel: "取消",
            remove: "移除",
            retry: "重试",
            select: "请选择...",
            statusUploaded: "已完成",
            statusFailed: "上传失败",
            statusUploading: "上传中..."
        }
    });
}

或者直接在文件加载时,某个元素被点击是加载:

  <script>
        $(document).ready(function() {
            $("#files").kendoUpload({
                async: {
                    saveUrl: "save",
                    removeUrl: "remove",
                    autoUpload: true
                }
            });
        });
    </script>

2.2、使用AngularJS上传文件

 <p>
        <input id="fileUpload" type="file" />
        <button ng-click="ok()">上传</button><br>
        <input ng-model="user.username" />
        <input ng-model="user.password" />
    </p>
 $scope.ok = function () {
        var form = new FormData();        var file = document.getElementById("fileUpload").files[0];   
        var user =JSON.stringify($scope.user);

        form.append('file', file);
        form.append('user',user);        $http({
            method: 'POST',
            url: '/addUser',
            data: form,
            headers: {'Content-Type': undefined},
            transformRequest: angular.identity
        }).success(function (data) {
            console.log('operation success');
        }).error(function (data) {
            console.log('operation fail');
        })
    };

后台:

@RequestMapping("/upload")    
public Map<String, Object> upload(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "user", required = true) String user) { 
       try {
		    FileInputStream in = (FileInputStream) headImg.getInputStream();
		    //将Json对象解析为UserModel对象
		    FileOutputStream out = new FileOutputStream("filePathAndName")) 
		    ObjectMapper objectMapper = new ObjectMapper();
		    UserModel userModel = objectMapper.readValue(user, UserModel.class); 
		    //保存文件到filePathAndName          
            int hasRead = 0;
            byte[] bytes = new byte[1024];            
            while ((hasRead = in.read(bytes)) > 0) {                
            out.write(bytes, 0, hasRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2.3、使用elementUI组件实现上传

<el-upload
  class="upload-demo"
  action="https://jsonplaceholder.typicode.com/posts/"
  :on-preview="handlePreview"
  :on-remove="handleRemove"
  :before-remove="beforeRemove"
  multiple
  :limit="3"
  :on-exceed="handleExceed"
  :file-list="fileList">
  <el-button size="small" type="primary">点击上传</el-button>
  <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
<script>
  export default {
    data() {
      return {
        fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
      };
    },
    methods: {
      handleRemove(file, fileList) {
        console.log(file, fileList);
      },
      handlePreview(file) {
        console.log(file);
      },
      handleExceed(files, fileList) {
        this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
      },
      beforeRemove(file, fileList) {
        return this.$confirm(`确定移除 ${ file.name }`);
      }
    }
  }
</script>

后端代码跟2.2同理。

3、知识扩展

  • 上传大文件时,怎么快速向服务器写视频数据,最快的组合是使用字节缓冲流+字节数组的方案最快。
  • 写文档文件时使用字符流reader/writer更好,而其他类型的文件时使用inputsteam/outputsteam更好。

参考链接

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bst@微胖子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值