- 几个踩坑的点 服务器我用的是windows系统的 服务器文件路径是D:Download/pdf 这样 本地的是D:\\Download\\pdf
其次上传文件本来是通过MultipartFile类型上传,我查询很多种方式转为File,但是生成的文件打不开,现在也不理解为什么要是知道的话可以给我回复一下,T.T(我通过上传MultipartFile文件下载到本地在把本地的上传到服务器避过了这个问题)
ps1.服务器有没有开通sftp可以通过telnet ip地址 端口号 这样看能不能进入(默认端口号是22)
ps2.通过服务器拉去数据的时候需要通过我这样写不然会发现返回的流不全,到时候会出现问题
<dependency>
<groupId>org.glassfish.external</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
/**
*
* @param pdfSaveFilePathIUPP ip,账号,密码,端口号
* @param fileNames 文件
* @param fileName 文件名
* @param fileInPath 上传路径
* @throws Exception
*/
public static boolean upload(String pdfSaveFilePathIUPP,String fileNames, String fileName, String fileInPath)
throws Exception {
String filePdfName = fileName + ".pdf";
File file = new File(fileNames + filePdfName);
byte[] bytes = getByteStream(file);
Channel channel = null;
Session session = connectSftp(pdfSaveFilePathIUPP);
OutputStream outstream = null;
try {
// 创建sftp通信通道
channel = (Channel) session.openChannel("sftp");
channel.connect(1000);
ChannelSftp sftp = (ChannelSftp) channel;
// 进入服务器指定的文件夹
String pathArry[] = fileInPath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString(), sftp)) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
// 进入并设置为当前目录
sftp.cd(filePath.toString());
}
}
outstream = sftp.put(filePdfName);
outstream.write(bytes);
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
// 关流操作
if (outstream != null) {
outstream.flush();
outstream.close();
}
if (session != null) {
session.disconnect();
}
if (channel != null) {
channel.disconnect();
}
}
return true;
}
/**
* 下载文件后转为base64
* @param pdfSaveFilePathIUPP
* @param fileName 文件名
* @param fileInPath 服务器地址
* @param localPath 本地地址
* @return
* @throws Exception
*/
public static String download(String pdfSaveFilePathIUPP,String fileName, String fileInPath,String localPath) throws Exception {
Channel channel = null;
Session session = connectSftp(pdfSaveFilePathIUPP);
try {
// 创建sftp通信通道
channel = (Channel) session.openChannel("sftp");
channel.connect(1000);
ChannelSftp sftp = (ChannelSftp) channel;
// 进入服务器指定的文件夹
String pathArry[] = fileInPath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString(), sftp)) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
// 进入并设置为当前目录
sftp.cd(filePath.toString());
}
}
if (isDirExist(filePath.toString(), sftp)) {
sftp.cd(filePath.toString());
InputStream inputStream = sftp.get(filePath.toString() + fileName );
byte[] data = null;
byte[] bytes = IOUtils.toByteArray(inputStream);
inputStream = new ByteArrayInputStream(bytes);
data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
//对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
String base64Pdf = encoder.encode(data);
// System.out.println(base64Pdf);
// sftp.get(filePath.toString() +fileName, localPath+"/"+ fileName);
return base64Pdf;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null) {
session.disconnect();
}
if (channel != null) {
channel.disconnect();
}
}
return null;
}
/**
* 登录ftp电脑
* @param pdfSaveFilePathIUPP ip 账号 密码 端口号
* @return
*/
private static Session connectSftp(String pdfSaveFilePathIUPP){
Session session = null;
String [] upm = pdfSaveFilePathIUPP.split(",");
String ip = upm[0];
String user = upm[1];
String password = upm[2];
int port = Integer.parseInt(upm[3]);
JSch jsch = new JSch();
try {
if (port <= 0) {
// 连接服务器,采用默认端口
session = jsch.getSession(user, ip);
} else {
// 采用指定的端口连接服务器
session = jsch.getSession(user, ip, port);
}
// 如果服务器连接不上,则抛出异常
if (session == null) {
throw new Exception("session is null");
}
// 设置登陆主机的密码
session.setPassword(password);// 设置密码
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)]
// session.setConfig("kex", "diffie-hellman-group1-sha1");
session.setConfig("StrictHostKeyChecking", "no");
// 设置登陆超时时间
session.connect(30000);
} catch (Exception e) {
throw new RuntimeException(e);
}
return session;
}
/**
* 判断目录是否存在
*/
public static boolean isDirExist(String directory, ChannelSftp sftp) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = sftp.lstat(directory);
isDirExistFlag = true;
return sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
/**
* 把文件转成流并删除原文件
* @param file
* @return
*/
public static byte[] getByteStream(File file) {
byte[] buffer = null;
FileInputStream fis;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
fis = new FileInputStream(file);
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
if (file.exists()) {
file.delete();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer;
}
验证base64 流是否可以生成pdf文件
static BASE64Decoder decoder = new sun.misc.BASE64Decoder();
/**
* 将base64编码转换成PDF
* @param base64sString
* 1.使用BASE64Decoder对编码的字符串解码成字节数组
* 2.使用底层输入流ByteArrayInputStream对象从字节数组中获取数据;
* 3.建立从底层输入流中读取数据的BufferedInputStream缓冲输出流对象;
* 4.使用BufferedOutputStream和FileOutputSteam输出数据到指定的文件中
*/
static void base64StringToPDF(String base64sString){
BufferedInputStream bin = null;
FileOutputStream fout = null;
BufferedOutputStream bout = null;
try {
//将base64编码的字符串解码成字节数组
byte[] bytes = decoder.decodeBuffer(base64sString);
//apache公司的API
//byte[] bytes = Base64.decodeBase64(base64sString);
//创建一个将bytes作为其缓冲区的ByteArrayInputStream对象
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
//创建从底层输入流中读取数据的缓冲输入流对象
bin = new BufferedInputStream(bais);
//指定输出的文件
File file = new File("D:\\pdf\\xxxss.pdf");
//创建到指定文件的输出流
fout = new FileOutputStream(file);
//为文件输出流对接缓冲输出流对象
bout = new BufferedOutputStream(fout);
byte[] buffers = new byte[1024];
int len = bin.read(buffers);
while(len != -1){
bout.write(buffers, 0, len);
len = bin.read(buffers);
}
//刷新此输出流并强制写出所有缓冲的输出字节,必须这行代码,否则有可能有问题
bout.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bin.close();
fout.close();
bout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}