本篇文章给大家带来的内容是关于js中以16进制字符串的形式进行多文件上传和下载(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
最近在维护一个比较老的 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 代码:
<input type="file" multiple="multiple" onchange="readfilesandupload(event)" />
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<string> filenamearr, list<string> 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) }}
以上就是js中以16进制字符串的形式进行多文件上传和下载(代码示例)的详细内容。