一.前言
根据客户反馈,在进行文件下载的时候,新增远程共享目录,下载对应的文件到远程共享目录,采用常用的IO操作模式,提示下载成功,但是客户去远程共享目录查看对应的下载文件,反馈说没有找到对应的文件。要求系统需要支持上传远程共享目录,为什么有一个这样的需求?由于下载的文件涉及到了支付文件,里面的金额不允许进行修改,如果放在本地路径有可能会不会出现人为的修改,一般涉及到钱的问题,客户都是比较谨慎的,刚好没有接触过操作远程共享目录的,就google了一下看有没有对应的操作说明,下面简单总结一下。
二.远程共享目录操作
1、需要下载对应的jcifs-1.3.18.jar,本例子采用3.18版本的,下载链接:https://jcifs.samba.org/
2、涉及的主要类是 SmbFile(远程文件操作类) ,还有就是进行登录验证,验证对应的远程目录的合法性的操作,其他操作就普通的IO流的操作。
3、从远程共享目录下载文件
/** * 方法说明:从远程共享目录下载文件 * @param localDir 本地临时路径 * @param removeDir 远程共享路径 * @param _fileName 远程共享文件名 * @param removeIp 远程共享目录IP * @param removeLoginUser 远程共享目录用户名 * @param removeLoginPass 远程共享目录密码 * @return * @throws Exception */ public static int smbDownload(String localDir, String removeDir, String _fileName, String removeIp, String removeLoginUser, String removeLoginPass) throws Exception { InputStream in = null; OutputStream out = null; try { NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication( removeIp, removeLoginUser, removeLoginPass); SmbFile remoteFile = new SmbFile(removeDir + _fileName, auth); if (!remoteFile.exists()) { return 0; } File dir = new File(localDir); if (!dir.exists()) { dir.mkdirs(); } String fileName = _fileName.substring(_fileName.lastIndexOf("\\")+1, _fileName.length()); File localFile = new File(localDir + fileName); in = new BufferedInputStream(new SmbFileInputStream(remoteFile)); out = new BufferedOutputStream(new FileOutputStream(localFile)); byte[] buffer = new byte[1024]; while (in.read(buffer) != -1) { out.write(buffer); buffer = new byte[1024]; } } catch (Exception e) { e.printStackTrace(); } finally { try { if (null != out) { out.close(); } } catch (IOException e) { e.printStackTrace(); } finally { if (null != in) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } return 1; }
4、上传文件都远程共享目录
/** * 方法说明:上传文件到远程共享目录 * @param localDir 本地临时路径(A:/测试/测试.xls) * @param removeDir 远程共享路径(smb://10.169.2.xx/测试/,特殊路径只能用/) * @param removeIp 远程共享目录IP(10.169.2.xx) * @param removeLoginUser 远程共享目录用户名(user) * @param removeLoginPass 远程共享目录密码(password) * @return * @throws Exception 0成功/-1失败 */ public static int smbUploading(String localDir, String removeDir, String removeIp, String removeLoginUser, String removeLoginPass) throws Exception { NtlmPasswordAuthentication auth = null; OutputStream out = null; int retVal = 0; try { File dir = new File(localDir); if (!dir.exists()) { dir.mkdirs(); } InetAddress ip = InetAddress.getByName(removeIp); UniAddress address = new UniAddress(ip); // 权限验证 auth = new NtlmPasswordAuthentication(removeIp, removeLoginUser, removeLoginPass); SmbSession.logon(address,auth); //远程路径判断文件文件路径是否合法 SmbFile remoteFile = new SmbFile(removeDir + dir.getName(), auth); remoteFile.connect(); if(remoteFile.isDirectory()){ retVal = -1; } // 向远程共享目录写入文件 out = new BufferedOutputStream(new SmbFileOutputStream(remoteFile)); out.write(toByteArray(dir)); } catch (UnknownHostException e) { retVal = -1; e.printStackTrace(); } catch (MalformedURLException e) { retVal = -1; e.printStackTrace(); } catch (SmbException e) { retVal = -1; e.printStackTrace(); } catch (IOException e) { retVal = -1; e.printStackTrace(); } finally{ if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } return retVal; } /** * Mapped File way MappedByteBuffer 可以在处理大文件时,提升性能 * * @param file 文件 * @return 字节数组 * @throws IOException IO异常信息 */ @SuppressWarnings("resource") public static byte[] toByteArray(File file) throws IOException { FileChannel fc = null; try { fc = new RandomAccessFile(file, "r").getChannel(); MappedByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0, fc.size()).load(); byte[] result = new byte[(int) fc.size()]; if (byteBuffer.remaining() > 0) { byteBuffer.get(result, 0, byteBuffer.remaining()); } return result; } catch (IOException e) { e.printStackTrace(); throw e; } finally { try { fc.close(); } catch (IOException e) { e.printStackTrace(); } } }