hdfs上传文件
前端
- 样式
<el-upload
class="upload-demo"
:action="serverUrl1"
name="file"
style="float: left;margin-left: 10px"
:before-upload="beforeDo1"
:on-success="uploadSuccess1"
:on-error="uploadError1"
:show-file-list="true"
>
<el-button size="small" type="primary">上传模型图片</el-button>
</el-upload>
- data
serverUrl1: 'http://localhost:8080/warheadModel/uploadFile1',
- 上传前、上传成功和失败的方法
// 上传图片文件
beforeDo1() {
this.flag1 = true //用来控制上传成功才能点击确定提交
},
uploadSuccess1(res, file) {
if (res.code === 200 && res.data !== null) {
console.log(res.data['url'])
this.stlForm.warhead_img_path = res.data['folder']
this.stlForm.warhead_img_name = res.data['name']
}
this.flag1 = false
},
uploadError1(res, file) {
this.$message.error('上传失败')
this.flag1 = false
},
后端
- controller
@ApiOperation(value = "上传模型图片")
@RequestMapping(value = "/uploadFile1", method = RequestMethod.POST)
@ResponseBody
public CommonResult<JSONObject> uploadFile1(@RequestParam(value="file") MultipartFile[] files) {
JSONObject object = warheadModelService.uploadFile1(files);
String path = object.get("url").toString();
System.out.println(path);
if(path!=null) {
return CommonResult.success(object);
}
return CommonResult.failed();
}
- serviceimpl
private String tempPath="D:\\temp\\"; //本地暂存文件夹路径
private String imgPath="/warhead/warhead/img/"; //hdfs中文件夹的相对路径,绝对路径为
//http://tdh-2:50070/explorer.html#/hs/warhead/warhead/img/
@Override
public JSONObject uploadFile1(MultipartFile[] files) {
String pathfrom = tempFile(files, tempPath);
JSONObject object = new JSONObject();
if(pathfrom!=null){
String url = HdfsUtil.uploadFile(tempPath+pathfrom, imgPath+pathfrom);
System.out.println(url);
deletefiles(tempPath+pathfrom);
String name = url.split("/")[url.split("/").length-1]; //获取文件名
System.out.println(name);
String folder = "http://tdh-2:50070/explorer.html#/hs" + imgPath;
System.out.println(folder);
object.put("url",url);
object.put("folder",folder);
object.put("name",name);
System.out.println(object);
return object;
}
return null;
}
- Hdfsutil中上传文件的方法(可以直接用)
public static String uploadFile(String pathFrom, String pathTo){
try {
LOGGER.info("hdfs上传文件");
FileSystem fileSystem = HdfsUtil.GetHdfsClient();
/*首先判断目标路径是否存在 不存在则创建文件夹(其实hdfs底层代码会自动创建目标文件夹的 但是就是有莫名其妙的错误)*/
if (!fileSystem.exists(new Path(defaultHdfsPath+pathTo))){
makeDir(defaultHdfsPath+pathTo);
}
/*在目标文件夹内部创建 yyyy-MM-dd-HH-mm-ss-随机码 格式的子文件夹 */
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MMdd-HHmmss");
// String dateForName = sdf.format(new Date());
// String pathToFinal = defaultHdfsPath + pathTo + "/" + dateForName + "-" + UUID.randomUUID().toString().replace("-","");
// makeDir(pathToFinal);
/*调用hdfs底层函数 上传文件*/
fileSystem.copyFromLocalFile(false,true,new Path(pathFrom),new Path(defaultHdfsPath+pathTo));
fileSystem.close();
String pathToFinal2 = "http://tdh-2:50070/explorer.html#"+defaultHdfsPath+pathTo;
LOGGER.info("hdfs上传文件完毕 url: " + pathToFinal2);
return pathToFinal2;
} catch (IOException e) {
e.printStackTrace();
return "upload failure";
}
}
hdfs下载文件
前端
- 样式
<el-button type="text" size="small" style="margin:0" @click="getFileStl(scope.row)">下载模型</el-button>
- js
getFileStl(row) {
if (row.warhead_model_path !== '' && row.warhead_model_name !== '' && row.warhead_model_path !== ' ' && row.warhead_model_name !== ' ') { //
this.downloadIngVisible = true
this.stlModelPath = row.warhead_model_path + row.warhead_model_name //文件在hdfs绝对路径
console.log(this.stlModelPath)
this.$http.get('http://localhost:8080/warheadModel/getFile', { params: {
path: this.stlModelPath
}},
{ headers: { 'Content-Type': 'application/json' }}).then((response) => {
if (response.data.code === 200) {
this.$message({
type: 'success',
message: '下载文件成功,文件存储于:' + response.data.data
})
console.log(response.data)
this.downloadedPath = response.data.data
this.downloadIngVisible = false
this.downloadFinishVisible = true
} else {
this.$message({
type: 'error',
message: '失败'
})
this.downloadIngVisible = false
}
})
} else {
this.nullFileVisible = true
}
},
后端
- controller
@ApiOperation(value = "下载文件")
@RequestMapping(value = "/getFile", method = RequestMethod.GET)
@ResponseBody
public CommonResult<String> getFile(@RequestParam(value = "path") String path) throws IOException {
// 下载文件路径不是http开头的绝对路径,用相对路径下,如:"/hs/warhead/warhead/img/***"
String[] path0 = path.split("#");
System.out.println(path0[1]);
String pathFrom= path0[1]; //相对路径,可以上传方法修改一下直接在数据库存相对路径,就不用解析上面的了,我已经写好了就懒得改了
String pathTo = "D:/hs_download/image";
String s =hdfsUtil.downloadFile_file(pathFrom,pathTo);
System.out.println(s);
return CommonResult.success(s);
}
- hdfsutil中的下载文件方法
//下载文件并获取文件流——wp
/*源路径(文件 or 文件夹) 目标文件夹*/
public static String downloadFile_file(String pathFrom, String pathTo){
try {
LOGGER.info("hdfs下载文件");
FileSystem fileSystem = HdfsUtil.GetHdfsClient();
/*判断目标路径是否存在 不存在则创建文件夹(其实hdfs底层代码会自动创建目标文件夹的 但是就是有莫名其妙的错误)*/
File file = new File(pathTo);
if (!file.exists()) {
file.mkdirs();
}
/*在目标文件夹内部创建 yyyy-MM-dd-HH-mm-ss-随机码 格式的子文件夹 */
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String dateForName = sdf.format(new Date());
String pathToFinal = pathTo + "\\" + dateForName + "-" + UUID.randomUUID().toString().replace("-","");
//String pathToFinal = pathTo + "/" + dateForName + "-" + UUID.randomUUID().toString().replace("-","");
new File(pathToFinal).mkdirs();
/*目标路径 例如 d://*/
fileSystem.copyToLocalFile(false,new Path(pathFrom),new Path(pathToFinal),true);
fileSystem.close();
String p = pathFrom.split("/")[pathFrom.split("/").length-1];
pathToFinal = pathToFinal+"/"+p+"/"+p;//本地路径
LOGGER.info("hdfs下载完毕" + pathToFinal);
return pathToFinal;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
hdfs文件流的获取(图片文件流获取、展示图片)
前端
我写的用弹窗显示图片,显示的逻辑是前端传hdfs路径和文件名给后端,获取图片字节流返回前端,前端用img显示。
- 样式
<el-button type="text" size="small" style="margin:0" @click="showStlImg(scope.row)">查看模型图片</el-button>
<el-dialog
:visible.sync="stlImgVisible"
width="400px"
>
<el-image
:src="picUrl"
:fit="fit"
/>
</el-dialog>
- js
showStlImg(row) {
if (row.warhead_img_path !== '' && row.warhead_img_name !== '' && row.warhead_img_path !== ' ' && row.warhead_img_name !== ' ') {
this.downloadIngVisible = true //下载中弹窗
this.stlImgPath = row.warhead_img_path + row.warhead_img_name
console.log(this.stlImgPath)
this.$http.get('http://localhost:8080/warheadModel/getImgBytes', { params: {
path: this.stlImgPath
}},
{ headers: { 'Content-Type': 'application/json' }}).then((response) => {
if (response.data.code === 200) {
this.$message({
type: 'success',
message: '成功'
})
console.log(response.data)
this.downloadIngVisible = false
this.stlImgVisible = true //图片弹窗
this.picUrl = 'data:image/png;base64,' + response.data.data //img组件绑定的url,需要前面加data:image/png;base64,,然后后面是字节流
} else {
this.$message({
type: 'error',
message: '失败'
})
this.downloadIngVisible = false
}
})
} else {
this.nullFileVisible = true
}
},
后端
- controller
@ApiOperation(value = "获取模型图片字节流")
@RequestMapping(value = "/getImgBytes", method = RequestMethod.GET)
@ResponseBody
public CommonResult<byte[]> getImgBytes(@RequestParam(value = "path") String path) throws IOException {
// 下载文件路径不是http开头的,是"/hs/warhead/warhead/img/***"
String[] path0 = path.split("#");
System.out.println(path0[1]);
String pathFrom= path0[1];
// String pathTo = "/hs/gzc/";
String pathTo = "D:/hs_download/image";
byte[] b =hdfsUtil.downloadFile_img(pathFrom,pathTo);
System.out.println(b.length);
return CommonResult.success(b);
}
- hdfsutil的获取字节流方法
逻辑是下载到本地临时文件夹,根据临时文件夹地址使用img2bytes方法(自己写的)将图片转化为字节流。
//下载文件并获取文件流——wp
/*源路径(文件 or 文件夹) 目标文件夹*/
public static byte[] downloadFile_img(String pathFrom, String pathTo){
try {
LOGGER.info("hdfs下载图片文件");
FileSystem fileSystem = HdfsUtil.GetHdfsClient();
/*判断目标路径是否存在 不存在则创建文件夹(其实hdfs底层代码会自动创建目标文件夹的 但是就是有莫名其妙的错误)*/
File file = new File(pathTo);
if (!file.exists()) {
file.mkdirs();
}
/*在目标文件夹内部创建 yyyy-MM-dd-HH-mm-ss-随机码 格式的子文件夹 */
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String dateForName = sdf.format(new Date());
String pathToFinal = pathTo + "\\" + dateForName + "-" + UUID.randomUUID().toString().replace("-","");
//String pathToFinal = pathTo + "/" + dateForName + "-" + UUID.randomUUID().toString().replace("-","");
new File(pathToFinal).mkdirs();
/*目标路径 例如 d://*/
fileSystem.copyToLocalFile(false,new Path(pathFrom),new Path(pathToFinal),true);
fileSystem.close();
String p = pathFrom.split("/")[pathFrom.split("/").length-1];
pathToFinal = pathToFinal+"/"+p+"/"+p;//本地路径
LOGGER.info("hdfs下载完毕" + pathToFinal);
byte[] b = image2bytes(pathToFinal);
return b;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static byte[] image2bytes(String imgSrc) throws Exception {
FileInputStream fin = new FileInputStream(imgSrc);
//可能溢出,简单起见就不考虑太多,如果太大就要另外想办法,比如一次传入固定长度byte[]
byte[] bytes = new byte[fin.available()];
//将文件内容写入字节数组,提供测试的case
fin.read(bytes);
fin.close();
return bytes;
}