基于springboot仿雀语的文档管理系统

项目介绍

本项目借鉴了雀语的一些UI设计,实现了文档在线管理的功能,知识库可以对不同分类的文档建立不同的库,知识库里面左边可以维护菜单菜单目录,右边实现在线预览。该项目可以防止用户下载和复制文档,只支持在线预览。

技术实现

文档上传的时候通过aspose把图片word和execel类型的文件转为pdf文件存储到nas,前端预览使用pdf.js加载预览pdf文档

项目预览

开发介绍

目录维护

左侧菜单点击加号可以维护目录

前端代码

<body class="white-bg"><div class="ibox-content"><form class="form-horizontal m-t" id="form1"><input id="id" name="id" type="hidden" /><input id="parentid" name="parentid" type="hidden" /><input id="deletemark" name="deletemark" type="hidden" /><input id="createdate" name="createdate" type="hidden" /><input id="createuserId" name="createuserId" type="hidden" /><input id="createusername" name="createusername" type="hidden" /><input id="modifydate" name="modifydate" type="hidden" /><input id="modifyuserid" name="modifyuserid" type="hidden" /><input id="modifyusername" name="modifyusername" type="hidden" /><div class="row"><div class="col-xs-12"><input type="text" id="name" class="form-control" placeholder="名称" /></div><div class="col-xs-12"><textarea id="remark" class="form-control" placeholder="描述" style="width:100%;height:100px;"></textarea></div><div class="col-xs-12"><input type="text" id="sortcode" class="form-control" placeholder="序号" /></div><div class="col-xs-12"><textarea id="keywords" class="form-control" placeholder="关键词" style="width:100%;height:100px;"></textarea></div></div></form></div>
</body>

后端代码

    @ApiOperation(value = "保存", notes = "")@PostMapping(value="/Save")public Result Save(@RequestBody String json) {DocmMenu model =  (DocmMenu) JSON.parseObject(json, DocmMenu.class);if(StrUtils.isBlank(model.getId())){model.setCreateuserid("admin");model.setDeletemark(new BigDecimal(0));model.setCreateusername("admin");model.setCreatedate(DateUtils.getNow());model.setId(UUID.randomUUID().toString());docmMenuService.add(model);}else {docmMenuService.update(model);}return Result.success(model,"成功!");}

文档维护

文档维护使用Dropzone实现前端文件上传,支持历史版本管理。

前端代码

<!DOCTYPE html>
<html>
<head><title>文档管理</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="shortcut icon" href="favicon.ico"><link href="../css/bootstrap.min.css" rel="stylesheet"><link href="../css/font-awesome.min.css" rel="stylesheet"><link href="../css/plugins/jsTree/style.min.css" rel="stylesheet"><link href="../css/plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet"><link href="../css/plugins/dropzone/dropzone.css" rel="stylesheet" type="text/css" /><!-- 全局js --><script src="../js/jquery.min.js"></script><script src="../js/bootstrap.min.js"></script><script src="../js/plugins/jsTree/jstree.min.js"></script><script src="../js/plugins/bootstrap-table/bootstrap-table.min.js"></script><script src="../js/plugins/layer/layer.min.js"></script><script src="../js/plugins/dropzone/dropzone.js"></script><script src="../js/bd-framework.js"></script></head>
<body class="white-bg">
<div><table id="table" style="width:100%"></table><div id="main-container" style="margin-top: 10px;"><form action="/" class="dropzone" enctype="multipart/form-data" id="my-dropzone"method="post"></form><textarea id="remark" class="form-control" placeholder="上传备注" style="width:100%;height:100px;"></textarea><div><!--上传按钮,提供多张图片一次性上传的功能--><button id="submit-all" class="btn btn-outline btn-default" type="submit" >上传</button></div></div></div>
<script>var $table = $('#table');$(function () {getFileList();})function getFileList() {$table.html("");$.get("/api/Attachment/getList?businessid="+GetQuery('businessid'), {}, function (result, resultState) {if (result.code == 200) {if (result.data.length > 0) {$table.append('<tr style="text-align: center; vertical-align: middle; border-style:solid; border-width:1px; ">'+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:30px;">序号</div></td>'+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:100px;">文件名称</div></td>'+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:80px;">上传人员</div></td>'+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:100px;">上传日期</div></td>'+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:200px;">备注</div></td>'+ '<td style="border-style:solid; border-width:1px;"><div style="padding:10px;width:50px;">操作</div></td>'+ '</tr>');for (var i = 0; i < result.data.length; i++) {if (result.data[i].EXTENSION != "pdf" || (result.data[i].TMP_BUSINESSID || '') =='') {$table.append('<tr style="border-style:solid; border-width:1px;">'+ '<td style="border-style:solid; border-width:1px;text-align:center;">' + (i + 1) + '</td>'+ '<td style="border-style:solid; border-width:1px;">'+ '<a onclick="Download(\'' + result.data[i].ID + '\')" style="float: left" href="javascript:void(0)"><u>' + result.data[i].NAME + '</u></a>'+ '</td>'+ '<td style="border-style:solid; border-width:1px;">' + result.data[i].CREATEUSERNAME + '</td>'+ '<td style="border-style:solid; border-width:1px;">' + result.data[i].CREATETIME + '</td>'+ '<td style="border-style:solid; border-width:1px;">' + (result.data[i].REMARK || '') + '</td>'+ '<td style="border-style:solid; border-width:1px;">'+ '<div style="position:relative;padding:10px;">'+ '<button type="button" onclick="FileDelete(\'' + result.data[i].ID + '\')" data-id="' + result.data[i].ID + '">'+ '删除'+ '</button>'+ '</div>'+ '</td>'+ '</tr>');}}}}})}function FileDelete(Id) {var index = parent.layer.confirm('是否删除?', {btn: ['是', '否'] //按钮}, function () {$.get("/api/Attachment/deleteByPDF", { id: Id }, function (result, resultState) {if (result.code == 200) {parent.layer.msg("删除成功!");getFileList();} else {parent.layer.msg(result.message);getFileList();}}, "json");parent.layer.close(index);}, function () {parent.layer.close(index);});}function Download(Id) {window.open('/api/Attachment/downFile?id=' + Id);};
</script>
<script>var loadIndex = null;//Dropzone的初始化,myDropzone为form的idDropzone.options.myDropzone = {params: {businessid: GetQuery('businessid'),filePath: 'DocM'// 您可以在这里添加其他参数},//指定上传的路径url: "/api/Attachment/uploadFilesToPDF",maxFiles: 1, // 用于限制此Dropzone将处理的最大文件数maxFilesize: 100, // MBacceptedFiles: ".doc,.docx,.pdf,.PDF,.jpg,.JPG,.gif,.GIF,.png,.PNG,.bmp,.BMP", // 上传的类型dictDefaultMessage:'<div style="text-align: center; vertical-align: middle;padding-top:38px;"><span>将文件拖拽到此处</span>  \<span>(或点击上传)</span></div>',dictResponseError: 'Error while uploading file!',dictFileTooBig: "最大100M",//添加上传取消和删除预览的链接,默认不添加addRemoveLinks: true,//关闭自动上传功能,默认会true会自动上传//也就是添加一张图片向服务器发送一次请求autoProcessQueue: false,//允许上传多个uploadMultiple: false,//记得修改web.config 限制上传文件大小的节parallelUploads: 100,init: function () {var submitButton = document.querySelector("#submit-all")myDropzone = this; // closure//为上传按钮添加点击事件submitButton.addEventListener("click", function () {Dropzone.options.myDropzone.params.remark = $("#remark").val();loadIndex = parent.layer.load();//手动上传所有文件myDropzone.processQueue();});//当添加图片后的事件,上传按钮恢复可用this.on("addedfile", function () {$("#submit-all").removeAttr("disabled");});//当上传完成后的事件,接受的数据为JSON格式this.on("complete", function (data) {parent.layer.close(loadIndex);if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) {var res = eval('(' + data.xhr.responseText + ')');var msg;if (res.code == 200) {msg = "已成功上传!";this.removeAllFiles();getFileList()}else {msg = "上传失败,失败的原因是:" + res.Message;}parent.layer.msg(msg);}});//删除文件的事件,当上传的文件为空时,使上传按钮不可用状态this.on("removedfile", function () {if (this.getAcceptedFiles().length === 0) {$("#submit-all").attr("disabled", true);}});}};
</script></body>

后端代码

    @CrossOrigin@ApiOperation(value = "文件上传并且转为PDF", notes = "")@PostMapping("/uploadFileToPDF")public Result uploadFileToPDF(@RequestBody byte[] fileByte,@RequestParam(value = "fileName",required = true) String fileName,@RequestParam(value = "filePath",required = true) String filePath,@RequestParam(value = "area",required = false) String area,@RequestParam(value = "businessid",required = false) String businessid,@RequestParam(value = "tmp_businessid",required = false) String tmp_businessid,@RequestParam(value = "createUserId",required = false) String createUserId,@RequestParam(value = "createUserName",required = false) String createUserName,@RequestParam(value = "remark",required = false) String remark) {try {String uuid = UUID.randomUUID().toString();// 获取文件名String extension = getFileExtension(fileName);String newFileName = uuid + "." + extension;DocM_Attachment attachment = new DocM_Attachment();attachment.setBusinessid(businessid);attachment.setFilename(fileName);DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyMMdd");String uploadPath = filePath + FileConnect + LocalDate.now().format(fmt);attachment.setId(uuid);attachment.setCreateTime(DateUtils.getNow());attachment.setDirectory(uploadPath);attachment.setFilepath(uploadPath + FileConnect + newFileName);attachment.setFileSize(bytesToMegabytes((long)fileByte.length));attachment.setArea(area);attachment.setTmp_businessid(tmp_businessid);attachment.setExtension(extension);attachment.setCreateUserId(createUserId);attachment.setCreateUserName(createUserName);attachment.setRemark(remark);SmbFileUtils.save(fileByte,uploadPath,newFileName);InputStream inputStream = new ByteArrayInputStream(fileByte);OutputStream pdfStream = null;if(extension.equals("docx") || extension.equals("doc")){pdfStream = doc2pdf(inputStream);}else if(extension.equals("png") || extension.equals("jpg") || extension.equals("gif")|| extension.equals("bmp")){pdfStream = image2pdf(inputStream);}DocM_Attachment pdfAttachment = new DocM_Attachment();BeanUtils.copyProperties(attachment,pdfAttachment);pdfAttachment.setId(UUID.randomUUID().toString());String newPdfFileName = pdfAttachment.getId() + ".pdf";pdfAttachment.setFilepath(uploadPath + FileConnect + newPdfFileName);pdfAttachment.setArea("pdf");pdfAttachment.setTmp_businessid(attachment.getId());pdfAttachment.setFilename(fileName.split("\\.")[0] + ".pdf");pdfAttachment.setExtension("pdf");SmbFileUtils.save(toByteArray(pdfStream),uploadPath,newPdfFileName);inputStream.close();pdfStream.close();attachmentService.add(attachment);attachmentService.add(pdfAttachment);return Result.success(uuid,"成功!");} catch (Exception e) {e.printStackTrace();return Result.failed("文件上传失败");}}

知识库详情页面

左侧菜单使用JSTree.js插件,右侧文档预览使用pdf.js插件

前端代码

<!DOCTYPE html>
<html>
<head><title>文档管理</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="shortcut icon" href="favicon.ico"><link href="../css/bootstrap.min.css" rel="stylesheet"><link href="../css/font-awesome.min.css" rel="stylesheet"><link href="../css/plugins/jsTree/style.min.css" rel="stylesheet"><link href="../css/plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet"><!-- 全局js --><script src="../js/jquery.min.js"></script><script src="../js/bootstrap.min.js"></script><script src="../js/plugins/jsTree/jstree.min.js"></script><script src="../js/plugins/bootstrap-table/bootstrap-table.min.js"></script><script src="../js/plugins/layer/layer.min.js"></script><script src="../js/bd-framework.js"></script>
</head>
<body class="white-bg"><style>.pdf{position:relative;    }.main_container{display:flex;}.left_container{width:320px;   border-right:1px solid #e7e9e8; overflow:scroll;}.right_contaner{flex:1;}#tree{}.jstree-anchor {font-size: 14px !important;/* color:#262626 !important;*/}.jstree-default .jstree-node {margin-top: 3px; /* 调整节点顶部的间距 */margin-bottom: 3px; /* 调整节点底部的间距 */}.btn-power{display:none;    }</style><div class="main_container"><div class="left_container"><div id="directoryExpand"><input type="text" id="Keywords" class="form-control" placeholder="关键词搜索" /><div style="display:flex; justify-content: space-between;align-items: center;margin-bottom:8px;padding:4px;"><div onclick="directoryExpand()" style="font-size: 14px;color:#262626;padding-left:25px;"><i class="fa fa-bars" style="margin-right:12px;"  ></i>目录</div><div><div style="position: absolute;margin-left:-90px;margin-top:-12px;" class="btn-power"><button data-toggle="dropdown" class="btn btn-outline btn-default dropdown-toggle" type="button" aria-expanded="false"><i class="glyphicon glyphicon-plus" aria-hidden="true"></i>     </button><button  onclick="btn_deleteAll()" class="btn btn-outline btn-default" type="button" ><i class="glyphicon glyphicon-trash" aria-hidden="true"></i>     </button><ul class="dropdown-menu pull-right"><li><a href="javascript:;" onclick="btn_add()">新建分组</a></li><li><a href="javascript:;" onclick="btn_edit()">编辑分组</a></li><li><a href="javascript:;" onclick="btn_uploadFile()">上传文档</a></li></ul></div></div></div><div id="tree"></div></div><div id="directoryNoExpand" style="display:none;"><div onclick="directoryNoExpand()" style="font-size: 14px;color:#262626;padding-left:12px;"><i class="fa fa-bars" ></i></div></div></div><div class="right_contaner"  ><div class="pdf" >       <iframe  id="iframe1" width="100%" height="100%" src="" frameborder="0" ></iframe></div></div></div><script>var currentNode = null;var loadIndex = null;function directoryExpand() {$("#directoryExpand").hide();$(".left_container").css("width", "40px");$("#directoryNoExpand").show();   }function directoryNoExpand() {$("#directoryExpand").show();$(".left_container").css("width", "320px");$("#directoryNoExpand").hide();}$(function () {getPower();$(this).bind("contextmenu", function (e) {e.preventDefault();});$(".left_container").height($(window).height() - 7);$(".pdf").height($(window).height() - 7);document.getElementById('iframe1').onload = function () {parent.layer.close(loadIndex);}$("#Keywords").keydown(function (event) {initTree();});})var isManager = false;function getPower() {$.get("/api/DocManage/IsPowerMange", { id: GetQuery('Id') }, function (result, resultState) {if (result.code == 200) {$(".btn-power").show();isManager = true;}initTree();}, "json");}var $tree = $('#tree');function initTree() {if (!!GetQuery('Id')) {var postData = {}postData.id = GetQuery('Id');postData.keywords = $("#Keywords").val();$.get("/api/DocManage/GetTreeJson", postData, function (result, resultState) {if (isManager) {$tree.on('activate_node.jstree', function (obj, e) {var node = e.node;if (node.id != undefined) {currentNode = node;loadPdf(node.id);}}).jstree({"multiple ": true,'plugins': ["checkbox"],'checkbox': {'three_state': false,'whole_node': false,'tie_selection': false // 只有点击复选框才能勾选节点},'core': {'data': result.data,'check_callback': function (operation, node, node_parent, node_position, more) {// 允许所有操作,包括创建、重命名、删除、移动和复制节点return true;}}})} else {$tree.on('activate_node.jstree', function (obj, e) {var node = e.node;if (node.id != undefined) {currentNode = node;loadPdf(node.id);}}).jstree({"multiple ": true,'core': {'data': result.data}})}}, "json");}}function loadPdf(businessid) {loadIndex = parent.layer.msg('文档加载中,请耐心等待!', { time: 1000 * 20 });$.get("/api/Attachment/getList?businessid="+businessid+"&area=pdf", {}, function (result, resultState) {if (result.code == 200) {if (result.data.length > 0) {for (var i = 0; i < result.data.length; i++) {if (result.data[i].EXTENSION == "pdf") {if (result.data[i].ID != currentNode.id) {$("#iframe1").attr("src", "../js/plugins/pdfjs-2.14.305-dist/web/DocManageViewer.html?file=" + "/api/Attachment/viewFile?id=" + result.data[i].ID);}break;}}} else {$("#iframe1").attr("src", "");parent.layer.close(loadIndex);}}}, "json");}function btn_add() {var viewData = {};if (currentNode) {viewData.parentid = currentNode.id;} else {viewData.parentid = GetQuery('Id')}var layerIndex = parent.layer.open({btn: ['确认'], //按钮yes: function (index, layero) {var postData = parent.$("#layui-layer-iframe" + index)[0].contentWindow.GetWebControls("#form1");$.ajax({url: "/api/DocManage/Save",type: "post",contentType: 'application/json',data: JSON.stringify(postData),dataType: "json",success: function (result) {parent.layer.close(layerIndex);// 在选中的节点下插入新节点$tree.jstree('create_node', currentNode, { text: result.data.name, id: result.data.id, icon: "no-icon" }, 'last', function (newNode) {//console.log('New node created with ID:', newNode.id);});}});},type: 2,title: '新增',area: ['350px', '550px'],shadeClose: true, //开启遮罩关闭content: '/docManage/menuEdit.html',success: function (layero, index) {parent.$("#layui-layer-iframe" + index)[0].contentWindow.SetWebControls(viewData);}});}function btn_edit() {var viewData = {};if (currentNode) {viewData.parentid = currentNode.id;} else {parent.layer.msg("请选择一个分组")return;}var layerIndex = parent.layer.open({btn: ['确认', '删除'], //按钮yes: function (index, layero) {var postData = parent.$("#layui-layer-iframe" + index)[0].contentWindow.GetWebControls("#form1");$.ajax({url: "/api/DocManage/Save",type: "post",contentType: 'application/json',data: JSON.stringify(postData),dataType: "json",success: function (result) {parent.layer.close(layerIndex);$tree.jstree('rename_node', currentNode, result.data.name);}});}, btn2: function (index, layero) {var index = parent.layer.confirm('是否删除?', {btn: ['是', '否'] //按钮}, function () {if (currentNode) {var postData = {};postData.id = currentNode.id;$.get("/api/DocManage/Delete", postData, function (result, resultState) {if (result.code == 200) {parent.layer.close(layerIndex);$tree.jstree('delete_node', currentNode);}}, "json");}parent.layer.close(index);}, function () {parent.layer.close(index);});},type: 2,title: '编辑',area: ['350px', '550px'],shadeClose: true, //开启遮罩关闭content: '/docManage/menuEdit.html',success: function (layero, index) {$.get("/api/DocManage/GetDetail", { id: currentNode.id }, function (result, resultState) {parent.$("#layui-layer-iframe" + index)[0].contentWindow.SetWebControls(result.data);}, "json");}});}function btn_deleteAll() {var index = parent.layer.confirm('是否删除?', {btn: ['是', '否'] //按钮}, function () {var postData = {};postData.ids = getTreeSelectedData().join(',');$.get("/api/DocManage/DeleteAll", postData, function (result, resultState) {parent.layer.close(index);$tree.jstree('delete_node', getTreeSelectedData());}, "json");}, function () {parent.layer.close(index);});}function btn_uploadFile() {var viewData = {};if (currentNode) {viewData.parentid = currentNode.id;} else {parent.layer.msg("请选择一个分组")return;}parent.layer.open({type: 2,title: '上传文档',area: ['850px', '750px'],shadeClose: true, //开启遮罩关闭content: '/docManage/uploadFileViewToPDF.html?businessid=' + currentNode.id,success: function (layero, index) {}});}function getTreeSelectedData() {var nodes = $tree.jstree("get_checked"); //使用get_checked方法return nodes;}</script></body>

文件转为pdf

使用aspose把文件转为pdf

    public OutputStream doc2pdf(InputStream inputStream) throws Exception {// 验证License 若不验证则转化出的pdf文档会有水印产生if (!getLicense()) {return null;}try {OutputStream outputStream =  new ByteArrayOutputStream();Document doc = new Document(inputStream);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换doc.save(outputStream, SaveFormat.PDF);return  outputStream;} catch (Exception e) {e.printStackTrace();throw new Exception("word转pdf失败");}}

访问nas

使用jcifs-ng访问nas

导入包

<!-- samba共享文件夹-->
<dependency><groupId>eu.agno3.jcifs</groupId><artifactId>jcifs-ng</artifactId><version>2.1.3</version>
</dependency>

工具栏

public class SmbFileUtils {static String ip = "";static String domain = "";static String userName = "";static String password = "";static void SmbFileUtils(){}//根据账号密码登录private static CIFSContext withNTLMCredentials(CIFSContext ctx) {return ctx.withCredentials(new NtlmPasswordAuthenticator(domain,userName, password));}//保存文件public static String save(byte[] byteArr, String url,String fileName) throws IOException {InputStream in = new ByteArrayInputStream(byteArr);String status = "";try {CIFSContext context = withNTLMCredentials(SingletonContext.getInstance());SmbFileWriter.createDirectory("smb://" + domain  +"/" + url, context);boolean result = SmbFileWriter.writeSmbFile(in, "smb://" + domain  +"/" + url +"/" + fileName, context);status = "success";} catch (Exception e) {e.printStackTrace();status = "error";} finally {in.close();return status;}}//获取文件public static  InputStream getFile(String filePath) throws IOException {String url = "smb://" + domain + "/" + filePath;try {CIFSContext context = withNTLMCredentials(SingletonContext.getInstance());SmbFileReader reader = new SmbFileReader();byte[] byteArr = reader.readSmbFile(url, context);InputStream input = new ByteArrayInputStream(byteArr);return  input;} catch (Exception e) {e.printStackTrace();}return null;}//删除文件public static String delete(String filePath) throws IOException {String status = "";String url = "smb://" + domain + "/" + filePath;try {CIFSContext context = withNTLMCredentials(SingletonContext.getInstance());SmbFile file = new SmbFile(url, context);if (file.exists()) {file.delete();status = "success";}} catch (Exception e) {e.printStackTrace();status = "error";}return status;}//获取文件列表public static  List<HashMap> getPathList(String path) throws IOException {String url = "smb://" + domain + "/" + path;List<HashMap> filesList = new ArrayList<>();CIFSContext context = withNTLMCredentials(SingletonContext.getInstance());try {SmbFile smbFile = new SmbFile(url, context);SmbFile[] files = smbFile.listFiles();for (SmbFile file : files) {HashMap fileMap =new HashMap();fileMap.put("fileName",file.getName());SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 定义日期格式fileMap.put("date",sdf.format(new Date(file.getDate())));fileMap.put("size", String.format("%.2f", (file.length()/1024.0)/1024.0)+"MB");fileMap.put("fileType",file.isDirectory()?"文件夹":"文件");filesList.add(fileMap);}} catch (Exception e) {e.printStackTrace();}return filesList;}static class SmbFileReader {public byte[] readSmbFile(String path, CIFSContext context) throws IOException {try  {SmbFile smbFile = new SmbFile(path, context);long fileSize = smbFile.length();if (fileSize > Integer.MAX_VALUE) {System.out.println("file too big...");return null;}InputStream fi = smbFile.getInputStream();byte[] buffer = new byte[(int) fileSize];int offset = 0;int numRead = 0;while (offset < buffer.length&& (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {offset += numRead;}// 确保所有数据均被读取if (offset != buffer.length) {throw new IOException("Could not completely read file "+ smbFile.getName());}fi.close();return buffer;} catch (Exception e) {e.printStackTrace();}return null;}}static class SmbFileWriter {static boolean writeSmbFile(String source, String target, CIFSContext context) throws IOException {if (StrUtils.isEmpty(source) || StrUtils.isEmpty(target)) {return false;}return writeSmbFile(Files.newInputStream(Paths.get(source)),target, context);}static boolean writeSmbFile(InputStream in, String target, CIFSContext context) throws IOException {if (Objects.nonNull(in) && StrUtils.isNotEmpty(target)) {try (SmbFile file = new SmbFile(target, context)) {try (SmbFile parent = new SmbFile(file.getParent(), context)) {if (!parent.exists()) {createDirectory(file.getParent(), context);}if (!file.exists()) {file.createNewFile();}}try (OutputStream os = file.getOutputStream()) {byte[] bytes = new byte[1024];while (in.read(bytes) != -1) {os.write(bytes);}return true;}}finally {in.close();}}return false;}static SmbFile createDirectory(String targetDir, CIFSContext context) throws MalformedURLException,CIFSException, MalformedURLException {try (SmbFile dir = new SmbFile(targetDir, context)) {if (!dir.exists()) {dir.mkdir();}return dir;}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/813008.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TSINGSEE青犀AI智能分析网关V4吸烟/抽烟检测算法介绍及应用

抽烟检测AI算法是一种基于计算机视觉和深度学习技术的先进工具&#xff0c;旨在准确识别并监测个体是否抽烟。该算法通过训练大量图像数据&#xff0c;使模型能够识别出抽烟行为的关键特征&#xff0c;如烟雾、手部动作和口部形态等。 在原理上&#xff0c;抽烟检测AI算法主要…

Dockerfile中 CMD和ENTRYPOINT的区别

在 Dockerfile 中&#xff0c;CMD 和 ENTRYPOINT 都用于指定容器启动时要执行的命令。它们之间的主要区别是&#xff1a; - CMD 用于定义容器启动时要执行的命令和参数&#xff0c;它设置的值可以被 Dockerfile 中的后续指令覆盖&#xff0c;包括在运行容器时传递的参数。如果…

Angular 13新特性概览与升级指南

Angular 13是Angular框架的最新版本&#xff0c;它引入了一些新的特性和改进。下面是Angular 13的一些新特性概览和升级指南&#xff1a; Ivy Renderer改进&#xff1a;Angular 13进一步改进了Ivy渲染器&#xff0c;提供更好的性能和更小的包大小。这意味着你可以在应用程序中获…

如何测试PostgreSQL数据库的性能

在这篇博客里&#xff0c;我将展示如何测量 PostgreSQL 数据库服务器的性能&#xff0c;并指导你如何运行一个基准测试。 基准测试旨在评估和比较不同配置、拓扑结构、系统和组件的性能。为此&#xff0c;我将使用 pgbench 工具。 你可能会问&#xff0c;为什么要使用一个单独…

Java 语言程序设计(基础篇)原书第10版 梁勇著 PDF 文字版电子书

简介 Java 语言程序设计&#xff08;基础篇&#xff09;原书第 10 版 是 Java 语言的经典教材&#xff0c;中文版分为基础篇和进阶篇&#xff0c;主要介绍程序设计基础、面向对象程序设计、GUI 程序设计、数据结构和算法、高级 Java 程序设计等内容。本书通过示例讲解问题求解…

蓝桥杯嵌入式(G431)备赛——最后一晚查漏补缺

蓝桥杯嵌入式&#xff08;G431&#xff09;备赛笔记——初始化cubeMX 蓝桥杯嵌入式&#xff08;G431&#xff09;备赛笔记——LED 蓝桥杯嵌入式&#xff08;G431&#xff09;备赛笔记——按键模块设计 蓝桥杯嵌入式&#xff08;G431&#xff09;备赛笔记——LCD按键 蓝桥杯…

杂货铺 | Linux虚拟机Ubuntu操作系统下设置共享文件夹(以及找不到hgfs文件夹怎么办)

文章目录 &#x1f4da;步骤一&#xff1a;配置共享文件夹&#x1f4da;步骤二&#xff1a;配置挂载环境&#x1f4da;步骤三&#xff1a;解决权限问题&#x1f4da;步骤四&#xff1a;解决重启失效问题 &#x1f4da;步骤一&#xff1a;配置共享文件夹 建立本地共享文件夹&…

07.QT信号和槽-2

一、自定义信号和槽 在Qt中&#xff0c;允许⾃定义信号的发送⽅以及接收⽅&#xff0c;即可以⾃定义信号函数和槽函数。但是对于⾃定义的信号函数和槽函数有⼀定的书写规范。 1.基本语法 1.1 自定义信号 &#xff08;1&#xff09;⾃定义信号函数必须写到"signals"…

2024 DTC大会精彩演讲:DBdoctor,基于eBPF重新定义数据库可观测 (附PPT下载和演讲视频)

由中国DBA联盟&#xff08;ACDU&#xff09;和墨天轮社区联合主办的第十三届数据技术嘉年华&#xff08;DTC&#xff09;于北京盛大召开。4月13日上午海信聚好看云平台负责人张纪宽受邀在『数据库生态软件』分论坛发表主题演讲《DBdoctor&#xff1a;利用eBPF技术实现数据库智能…

微信小程序公共组件封装使用

1.在components目录下创建公共组件&#xff0c;以navbar为例 2.完成组件功能 3.调用&#xff0c;如果很多地方都会用到&#xff0c;建议放全局&#xff0c;如果不是则放在需要引用的文件中 3.1全局引用&#xff0c;在app.json做全局引用配置 3.2局部引用&#xff0c;在需要引入…

springcloud第4季 springcloud-alibaba之nacos篇

一 nacos 1.1 nacos作用介绍 nacos是一个分布式的配置中心和注册发现中心。 nacos是 dynamic naming configuration service nacosconfigbus 实现动态刷新&#xff1b;nacosconsul 1.2 各个注册中心对比 注册中心CAP模型控制台管理社区活跃度EureakaAp支持低zkcp不支持中…

初学python记录:力扣2923. 找到冠军 I

题目&#xff1a; 一场比赛中共有 n 支队伍&#xff0c;按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 < i, j < n - 1 且 i ! j 的所有 i, j &#xff1a;如果 grid[i][j] 1&#xff0c;那么 i 队比 j 队 强 &…

Docker - PostgreSQL

博文目录 文章目录 说明命令 说明 Docker Hub PostgreSQL 数据卷数据卷印射在容器内的路径postgres/var/lib/postgresql/data |容器内的路径|说明| |–|–|–| |/var/lib/postgresql/data|数据目录| 部分环境变量是否必要说明POSTGRES_PASSWORD必需设置超级用户密码POSTGRES…

什么是队头阻塞以及如何解决

前言 通常我们提到队头阻塞&#xff0c;指的可能是TCP协议中的队头阻塞&#xff0c;但是HTTP1.1中也有一个类似TCP队头阻塞的问题&#xff0c;下面各自介绍一下。 TCP队头阻塞 队头阻塞&#xff08;head-of-line blocking&#xff09;发生在一个TCP分节丢失&#xff0c;导致…

LightDB 函数/存储过程支持在任意位置使用默认值【24.1】【oracle 兼容】

LightDB 函数/存储过程支持在任意位置使用默认值 在之前的版本中&#xff0c;在 LightDB 中创建的函数或存储过程&#xff0c;每个有默认值的参数后面的参数都需要有默认值&#xff08;同c中函数, 默认值从右向左赋值&#xff09;。 在 24.1 版本中支持oracle 中的默认值用法&…

Springboot+Vue项目-基于Java+MySQL的校园管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

PHP数组去重

public function array_unique_key($arr,$key) {$tmp_arrarray();foreach($arr as $k > $v){if(in_array($v[$key],$tmp_arr)){ //判断是否重复unset($arr[$k]); //重复则删除}else{$tmp_arr[]$v[$key]; //将值存储在临时数组中}}return $arr; } public function array…

裸机开发之汇编、寄存器

一、什么是汇编&#xff1f;为什么学汇编&#xff1f; 在之前写控制代码的时候就在想&#xff1a;底层是怎么控制的&#xff1f;后来经过学习知道之前所编写的代码都是应用层代码&#xff0c;顾名思义就是在系统写好的底层之上调用系统函数。原以为底层是指写系统写好的底层函数…

VRRP(虚拟路由冗余协议)详解

VRRP-------虚拟路由冗余协议 在一个网络中&#xff0c;要做为一个合格的网络首先就要具备几种冗余&#xff0c;增加网络的可靠性。 这几种冗余分别为&#xff1a;线路冗余&#xff0c;设备冗余&#xff0c;网关冗余&#xff0c;UPS冗余 VRRP该协议就是解决网关冗余的。在二层…

面经:MapReduce编程模型与优化策略详解

作为一名专注于大数据处理与分布式计算的博主&#xff0c;我深知MapReduce作为一款经典的分布式计算框架&#xff0c;在海量数据处理领域所起的关键作用。本篇博客将结合我个人的面试经历&#xff0c;深入剖析MapReduce编程模型与优化策略&#xff0c;分享面试必备知识点&#…