国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

多文件上傳和下載:以16進制字符串的形式傳輸

bluesky / 920人閱讀

摘要:現在要利用這個框架實現上傳文件到服務端和從服務端下載文件,然而這個項目用的,默認只支持調用以基本數據類型,以及等常用類型作為參數和返回值的方法,無法使用這些對象。既然可以傳遞字符串,那就采用文件與字符串互轉的方式進行前后交互。

1. 前言

最近在維護一個比較老的 Web 項目,其中用到了 DWR 2.0 (一種可以在 js 里調用 Java 方法的遠程通信框架)。現在要利用這個框架實現上傳文件到服務端和從服務端下載文件,然而這個項目用的 DWR 2.0,默認只支持調用以基本數據類型,以及String、 List、Map 等常用類型作為參數和返回值的 Java 方法,無法使用 FileTransfer、InputStream、MultipartFile 這些對象。

既然可以傳遞字符串,那就采用文件與字符串互轉的方式進行前后交互。流程如下:
上傳文件時,文件 -> ArrayBuffer -> 16 進制字符串 -> byte[] -> 文件
下載文件時,文件 -> byte[] -> 16 進制字符串 -> Uint8Array -> blob -> 文件

2. 上傳文件

HTML 代碼:

JS 代碼:

// 將 ArrayBuffer 轉為 16 進制字符串
function bufToHex(buffer) {
    return Array.prototype.map.call(new Uint8Array(buffer), function (x) {
        return ("00" + x.toString(16)).slice(-2)
    }).join("")
}

function readFilesAndUpload(event) {
    var processed = 0
    var files = event.target.files
    var len = files.length
    var filenameArr = new Array(len)    // 文件名
    var fileContextArr = new Array(len)    // 文件內容
    for (var i = 0; i < len; ++i) {
        var reader = new FileReader()
        reader.index = i
        reader.filename = files[i].name
        reader.readAsArrayBuffer(files[i])    // 將文件讀到 ArrayBuffer
        reader.onload = function (e) {
            filenameArr[this.index] = this.filename
            fileContextArr[this.index] = bufToHex(this.result)

            // FileReader 以異步的方式讀取文件,需要借助外部變量判斷是否讀完全部文件
            if (++processed === len) {
                // 將 filenameArr 和 fileContext 上傳到服務端
            }
        }
    }
}

Java 代碼:

private static final String UPLOAD_DIR = "D://Files/";

public void uploadFiles(List filenameArr, List fileContextArr) throws IOException {
    byte[] bytes;
    FileOutputStream fos;
    for (int i = 0; i < filenameArr.size(); ++i) {
        String file = fileContextArr.get(i);
        
        // 將 16 進制字符串轉換成 byte[]
        bytes = new byte[file.length() / 2];
        for (int j = 0; j < file.length() / 2; ++j) {
            String subStr = file.substring(j * 2, j * 2 + 2);
            bytes[j] = (byte) Integer.parseInt(subStr, 16);
        }

        // 保存到本地磁盤
        fos = new FileOutputStream(UPLOAD_DIR + filenameArr.get(i), true);
        fos.write(bytes);
        fos.close();
    }
}
3. 下載文件

Java 代碼:

public String downloadFile(String filename) throws IOException {
    File file = new File(UPLOAD_DIR + filename);
    if (!file.exists()) {
        return null;
    }
    
    // 將文件讀到 byte[]
    byte[] buffer = new byte[(int) file.length()];
    InputStream is = new FileInputStream(file);
    is.read(buffer);
    is.close();

    // 將 byte[] 轉換成 16 進制字符串
    StringBuilder stringBuilder = new StringBuilder();
    for (int i = 0; i < buffer.length; i++) {
        int v = buffer[i] & 0xFF;
        String hv = Integer.toHexString(v);
        if (hv.length() < 2) {
            stringBuilder.append(0);
        }
        stringBuilder.append(hv);
    }
    return stringBuilder.toString();
}

JS 代碼:

// 16 進制字符串轉換成整型數組
function hexToBytes(hexStr) {
    var bytes = []
    for (var c = 0; c < hexStr.length; c += 2)
        bytes.push(parseInt(hexStr.substr(c, 2), 16))
    return bytes
}

function downloadFile() {
    // 調用服務端方法,取得 16 進制字符串 res
    var uint8Array = new Uint8Array(hexToBytes(res))
    var blob = new Blob([uint8Array], {type: "application/octet-stream"})

    // 兼容 IE、火狐和谷歌的下載方式
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, filename)
    } else {
        var downloadElement = document.createElement("a")
        var href = window.URL.createObjectURL(blob)
        downloadElement.href = href
        downloadElement.download = filename
        document.body.appendChild(downloadElement)
        downloadElement.click()
        downloadElement.remove()
        window.URL.revokeObjectURL(href)
    }
}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101422.html

相關文章

  • 文件上傳下載16進制符串形式傳輸

    摘要:現在要利用這個框架實現上傳文件到服務端和從服務端下載文件,然而這個項目用的,默認只支持調用以基本數據類型,以及等常用類型作為參數和返回值的方法,無法使用這些對象。既然可以傳遞字符串,那就采用文件與字符串互轉的方式進行前后交互。 1. 前言 最近在維護一個比較老的 Web 項目,其中用到了 DWR 2.0 (一種可以在 js 里調用 Java 方法的遠程通信框架)。現在要利用這個框架實現...

    oogh 評論0 收藏0
  • 關于前端上傳文件全面基礎掃盲貼(一) ----- XMLHttpRequest

    摘要:狀態表示對象的狀態狀態描述未初始化。表示成功,表示未找到,表示服務器內部錯誤等。前提是瀏覽器必須支持這個功能,而且服務器端必須同意這種跨域。事件傳輸成功完成。 系列文章 關于前端上傳文件全面基礎掃盲貼(零)關于前端上傳文件全面基礎掃盲貼(一) ----- XMLHttpRequest關于前端上傳文件全面基礎掃盲貼(二) ----- File關于前端上傳文件全面基礎掃盲貼(三) ----...

    i_garfileo 評論0 收藏0
  • 前端必知必會HTTP請求系列(三)HTTP報文內http信息

    摘要:報文用于協議交互的信息被稱為報文。現在出現的各種首部字段及狀態碼稍后會闡述。狀態碼響應報文包含了多個范圍的內容使用。如果服務器無法響應范圍請求,則會返回狀態碼和完整的實體內容。 showImg(https://segmentfault.com/img/bVbthNL?w=900&h=500); http報文 用于HTTP協議交互的信息被稱為HTTP報文。請求端的http報文叫做請求報文...

    Invoker 評論0 收藏0
  • 使用Blob進行文件上傳

    摘要:構造函數創建對象本質上和創建一個其他對象的方式是一樣的,都是使用的構造函數來進行創建。構造函數接受兩個參數第一個參數為一個數據序列,格式可以是第二個參數是一個包含以下兩個屬性的對象的類型決定第一個參數的數據格式。 Blob,Binary Large Object的縮寫,二進制類型的大對象,代表不可改變的原始數據 Blob基本用法 Blob對象 Blob對象指的是字節序列,并且具有siz...

    cnsworder 評論0 收藏0
  • 使用Blob進行文件上傳

    摘要:構造函數創建對象本質上和創建一個其他對象的方式是一樣的,都是使用的構造函數來進行創建。構造函數接受兩個參數第一個參數為一個數據序列,格式可以是第二個參數是一個包含以下兩個屬性的對象的類型決定第一個參數的數據格式。 Blob,Binary Large Object的縮寫,二進制類型的大對象,代表不可改變的原始數據 Blob基本用法 Blob對象 Blob對象指的是字節序列,并且具有siz...

    EasonTyler 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<