熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java 文件分塊上傳服務器端源代碼

2013-11-23 19:12:15  來源: Java核心技術 

  直接上代碼接收客戶端 HTTP 分塊上傳請求的 Spring MVC 控制器源代碼如下
    [java]
    @Controller
    public class UploadController extends BaseController {
    private static final Log log = LogFactorygetLog(UploadControllerclass)
    private UploadService uploadService;
    private AuthService authService;
    /**
    * 大文件分成小文件塊上傳一次傳遞一塊最後一塊上傳成功後將合並所有已經上傳的塊保存到File Server
    * 上相應的位置並返回已經成功上傳的文件的詳細屬性 當最後一塊上傳完畢返回上傳成功的信息此時用getFileList查詢該文件
    * 該文件的uploadStatus為client請自行處理該狀態下文件如何顯示(for UPS Server)
    *
    */
    @RequestMapping(/core/v/file/upload
    @ResponseBody
    public Object upload(HttpServletResponse response
    @RequestParam(value = client_id required = false) String appkey
    @RequestParam(value = sig required = false) String appsig
    @RequestParam(value = token required = false) String token
    @RequestParam(value = uuid required = false) String uuid
    @RequestParam(value = block required = false) String blockIndex
    @RequestParam(value = file required = false) MultipartFile multipartFile
    @RequestParam Map<String String> parameters) {
    checkEmpty(appkey BaseExceptionERROR_CODE_
    checkEmpty(token BaseExceptionERROR_CODE_
    checkEmpty(uuid BaseExceptionERROR_CODE_
    checkEmpty(blockIndex BaseExceptionERROR_CODE_
    checkEmpty(appsig BaseExceptionERROR_CODE_
    if (multipartFile == null) {
    throw new BaseException(BaseExceptionERROR_CODE_// 上傳文件不存在
    }
    Long uuidL = parseLong(uuid BaseExceptionERROR_CODE_
    Integer blockIndexI = parseInt(blockIndex BaseExceptionERROR_CODE_
    Map<String Object> appMap = getAuthService()validateSigature(parameters)
    AccessToken accessToken = CasUtilcheckAccessToken(token appMap)
    Long uid = accessTokengetUid()
    String bucketUrl = accessTokengetBucketUrl()
    // 從上傳目錄拷貝文件到工作目錄
    String fileAbsulutePath = null;
    try {
    fileAbsulutePath = pyFile(multipartFilegetInputStream() multipartFilegetOriginalFilename())
    } catch (IOException ioe) {
    logerror(ioegetMessage() ioe)
    throw new BaseException(BaseExceptionERROR_CODE_// 上傳文件不存在
    }
    File uploadedFile = new File(GlobalUPLOAD_TEMP_DIR + fileAbsulutePath)
    checkEmptyFile(uploadedFile)// file 非空驗證
    Object rs = uploadServiceupload(uuidL blockIndexI uid uploadedFile bucketUrl)
    setHttpStatusOk(response)
    return rs;
    }

  // TODO 查看下這裡是否有問題
    // 上傳文件非空驗證
    private void checkEmptyFile(File file) {
    if (file == null || filegetAbsolutePath() == null) {
    throw new BaseException(BaseExceptionERROR_CODE_// 上傳文件不存在
    }
    }
    /**
    * 寫文件到本地文件夾
    *
    * @throws IOException
    *             返回生成的文件名
    */
    private String copyFile(InputStream inputStream String fileName) {
    OutputStream outputStream = null;
    String tempFileName = null;
    int pointPosition = fileNamelastIndexOf(
    if (pointPosition < ) {// myvedio
    tempFileName = UUIDrandomUUID()toString()// ddeaadddafbff
    } else {// myvedioflv
    tempFileName = UUIDrandomUUID() + fileNamesubstring(pointPosition)// ddeaadddafbffflv
    }
    try {
    outputStream = new FileOutputStream(GlobalUPLOAD_TEMP_DIR + tempFileName)
    int readBytes = ;
    byte[] buffer = new byte[];
    while ((readBytes = inputStreamread(buffer )) != ) {
    outputStreamwrite(buffer readBytes)
    }
    return tempFileName;
    } catch (IOException ioe) {
    // logerror(ioegetMessage() ioe)
    throw new BaseException(BaseExceptionERROR_CODE_// 上傳文件不存在
    } finally {
    if (outputStream != null) {
    try {
    outputStreamclose()
    } catch (IOException e) {
    }
    }
    if (inputStream != null) {
    try {
    inputStreamclose()
    } catch (IOException e) {
    }
    }
    }
    }
    /**
    * 測試此服務是否可用
    *
    * @param response
    * @return
    * @author zwq
    */
    @RequestMapping(/core/v/file/testServer
    @ResponseBody
    public Object testServer(HttpServletResponse response) {
    setHttpStatusOk(response)
    return GlobalSUCCESS_RESPONSE;
    }
    public UploadService getUploadService() {
    return uploadService;
    }
    public void setUploadService(UploadService uploadService) {
    thisuploadService = uploadService;
    }
    public void setAuthService(AuthService authService) {
    thisauthService = authService;
    }
    public AuthService getAuthService() {
    return authService;
    }
    }
    比如要上傳的文件是 testkmp對照《Java 文件分塊上傳客戶端源代碼》中分塊上傳服務器對分塊文件參數定義的名字fileupload 方法裡使用的是 MultipartFile 接收該對象對於每次的 HTTP 請求使用 copyFile 方法將文件流輸出到服務器本地的一個臨時文件夾裡比如作者的是 D:/defonds/syncPath/uploadTemp該文件下會有 bbafefdeadamp 臨時文件生成用於保存上傳文件流
    分塊依次上傳當所有塊都上傳完畢之後將這些臨時文件都轉移到服務器指定目錄中比如作者的這個目錄是 D:/defonds/syncPath/file在該文件夾下會有//temp_dir__ 目錄生成而 uploadTemp 的臨時文件則被挨個轉移到這個文件夾下生成形如 part 的文件以下是文件轉移的源代碼
    [java]
    /**
    * 把所有塊從臨時文件目錄移到指定本地目錄或S/S
    *
    * @param preUpload
    */
    private void moveBlockFiles(BlockPreuploadFileInfo preUpload) {
    @SuppressWarnings(unchecked
    String[] sBlockUrl=new String[preUploadgetBlockNumber()];
    String[] localBlockUrl=new String[preUploadgetBlockNumber()];//本地的塊文件路徑    以便以後刪除
    List<BlockUploadInfo> blocks = (List<BlockUploadInfo>) getBaseDao()queryForList(
    uploadgetBlockUploadFileByUuid preUploadgetUuid())
    String tempDirName = SyncUtilgetTempDirName(preUploadgetUuid() preUploadgetUid())
    String parentPath = GlobalUPLOAD_ABSOLUTE_PAHT_ + GlobalPATH_SEPARATIVE_SIGN
    + StringvalueOf(preUploadgetUid())
    String dirPath = parentPath + GlobalPATH_SEPARATIVE_SIGN + tempDirName;
    new File(dirPath)mkdirs()//創建存放塊文件的文件夾 (本地)
    int j=;
    for (BlockUploadInfo info : blocks) {
    try {
    String strBlockIndex = createStrBlockIndex(infogetBlockIndex())
    String suffixPath = preUploadgetUuid() + part + strBlockIndex;
    String tempFilePath = infogetTempFile()
    File tempFile = new File(tempFilePath)
    File tmpFile = new File(dirPath + suffixPath)
    if (tmpFileexists()) {
    FileUtilsdeleteQuietly(tmpFile)
    }
    FileUtilsmoveFile(tempFile tmpFile)
    localBlockUrl[j]=dirPath + suffixPath;
    j++;
    infosetStatus(GlobalMOVED_TO_NEWDIR)
    getBaseDao()update(uploadupdateBlockUpload info)
    if (logisInfoEnabled())
    (preUploadgetUuid() + + infogetBuId() + moveBlockFiles
    } catch (IOException e) {
    logerror(egetMessage() e)
    throw new BaseException(file not found
    }
    }
    preUploadsetLocalBlockUrl(localBlockUrl)
    preUploadsetDirPath(dirPath)
    preUploadsetStatus(GlobalMOVED_TO_NEWDIR)
    getBaseDao()update(uploadupdatePreUploadInfo preUpload)
    }
    private String createStrBlockIndex(int blockIndex) {
    String strBlockIndex;
    if (blockIndex < ) {
    strBlockIndex = + blockIndex;
    } else if ( <= blockIndex && blockIndex < ) {
    strBlockIndex = + blockIndex;
    } else if ( <= blockIndex && blockIndex < ) {
    strBlockIndex = + blockIndex;
    } else {
    strBlockIndex = + blockIndex;
    }
    return strBlockIndex;
    }
    最後是文件的組裝源代碼
    [java]
    /**
    * 組裝文件
    *
    */
    private void assembleFileWithBlock(BlockPreuploadFileInfo preUpload) {
    String dirPath = preUploadgetDirPath()
    // 開始在指定目錄組裝文件
    String uploadedUrl = null;
    String[] separatedFiles;
    String[][] separatedFilesAndSize;
    int fileNum = ;
    File file = new File(dirPath)
    separatedFiles = filelist()
    separatedFilesAndSize = new String[separatedFileslength][];
    Arrayssort(separatedFiles)
    fileNum = separatedFileslength;
    for (int i = ; i < fileNum; i++) {
    separatedFilesAndSize[i][] = separatedFiles[i];
    String fileName = dirPath + separatedFiles[i];
    File tmpFile = new File(fileName)
    long fileSize = tmpFilelength()
    separatedFilesAndSize[i][] = StringvalueOf(fileSize)
    }

  RandomAccessFile fileReader = null;
    RandomAccessFile fileWrite = null;
    long alreadyWrite = ;
    int len = ;
    byte[] buf = new byte[];
    try {
    uploadedUrl = GlobalUPLOAD_ABSOLUTE_PAHT_ + GlobalPATH_SEPARATIVE_SIGN + preUploadgetUid() + GlobalPATH_SEPARATIVE_SIGN + preUploadgetUuid()
    fileWrite = new RandomAccessFile(uploadedUrl rw
    for (int i = ; i < fileNum; i++) {
    fileWriteseek(alreadyWrite)
    // 讀取
    fileReader = new RandomAccessFile((dirPath + separatedFilesAndSize[i][]) r
    // 寫入
    while ((len = fileReaderread(buf)) != ) {
    fileWritewrite(buf len)
    }
    fileReaderclose()
    alreadyWrite += LongparseLong(separatedFilesAndSize[i][])
    }
    fileWriteclose()
    preUploadsetStatus(GlobalASSEMBLED)
    preUploadsetServerPath(uploadedUrl)
    getBaseDao()update(uploadupdatePreUploadInfo preUpload)
    if(GlobalBLOCK_UPLOAD_TO!=GlobalBLOCK_UPLOAD_TO_LOCAL)
    {
    //組裝完畢沒有問題  刪除掉S/S上的block
    String[] path=preUploadgetSBlockUrl()
    for (String string : path) {
    try {
    if(GlobalBLOCK_UPLOAD_TO==GlobalBLOCK_UPLOAD_TO_S
    {
    SUtildeleteFile(preUploadgetBucketUrl() string)
    }else
    {
    SUtildeleteFile(preUploadgetBucketUrl() string)
    }
    } catch (Exception e) {
    logerror(egetMessage() e)
    }
    }
    }
    if (logisInfoEnabled())
    (preUploadgetUuid() + assembleFileWithBlock
    } catch (IOException e) {
    logerror(egetMessage() e)
    try {
    if (fileReader != null) {
    fileReaderclose()
    }
    if (fileWrite != null) {
    fileWriteclose()
    }
    } catch (IOException ex) {
    logerror(egetMessage() e)
    }
    }
    }
    BlockPreuploadFileInfo 是我們自定義的業務文件處理 bean
    OK分塊上傳的服務器客戶端源代碼及其工作流程至此已全部介紹完畢以上源代碼全部是經過項目實踐過的大部分現在仍運行於一些項目之中有興趣的朋友可以自己動手將以上代碼自行改造看看能否運行成功如果遇到問題可以在本博客下跟帖留言大家一起討論討論


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26424.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.