1.第一步,引入bc包的安装依赖。
在pom.xml中引入。
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.60</version> </dependency>
引入后reimport一下项目。
2.pdf文件转换成Base64.
/**
* @Description:
* @param:
* @return:
* @author: TateBrown
* @Date: 2018/7/25
*/
@ApiOperation("根据docid返回pdf文件Base64编码")
@PostMapping("/FindPDFBase")
public R FindPDFBase(@PathVariable("signdocid") Integer signdocid){
FileInputStream fin=null;
BufferedInputStream bin=null;
ByteArrayOutputStream baos=null;
BufferedOutputStream bout=null;
try{
SignDocEntity signDoc = signDocService.selectById(signdocid);
String filepath=signDoc.getUrl();
File file=new File(filepath);
if(!file.exists()){
return R.error("文件不存在");
}
fin=new FileInputStream(file);
bin=new BufferedInputStream(fin);
baos=new ByteArrayOutputStream();
bout=new BufferedOutputStream(baos);
byte[] buffer=new byte[1024];
int len=bin.read(buffer);
while(len!=-1){
bout.write(buffer,0,len);
len=bin.read(buffer);
}
//读取完毕
bout.flush();
byte[] bytes=baos.toByteArray();
String res=Base64.toBase64String(bytes);
return R.ok("获取成功").put("Base64",res);
}catch(Exception e){
e.printStackTrace();
return R.error();
}finally {
try{
fin.close();
bin.close();
bout.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
总的思路就是,先弄几个文件流的引用,将文件转换成二进制流读取存到数组中,然后利用bc包中的Base64的函数toBase64String将二进制数组转换成Base64的操作。
3.Base64转换成pdf文件。
Base64一般比pdf文件要大一些,但是对于浏览器来说,Base64可以直接解析,做一个在线预览功能。而存储在服务器端一般使用.pdf文件来存储,一般不会用Base64存。所以Base64转换成pdf也是非常关键的。下面是源码。
/**
* @Description:Base64转换成pdf
* @param:
* @return:
* @author: TateBrown
* @Date: 2018/7/23
*/
@Override
public void BasetoPdffile(String pdfBase64Str,String filepath){
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try{
byte[] bytes=Base64.decode(pdfBase64Str);
ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes);
bis=new BufferedInputStream(byteArrayInputStream);
File file=new File(filepath);
File path=file.getParentFile();
if(!path.exists()){
path.mkdirs();
}
fos=new FileOutputStream(file);
bos=new BufferedOutputStream(fos);
byte[] buffer=new byte[1024];
int length=bis.read(buffer);
while(length!=-1){
bos.write(buffer,0,length);
length=bis.read(buffer);
}
bos.flush();
}catch(Exception e){
e.printStackTrace();
}finally {
try{
bis.close();
bos.close();
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
总的思路就是和上面的反过来,先将Base64利用bc包中的函数解析成二进制流。然后将二进制流写入文件即可。这里要注意的是FileOutputStream这个构造函数。我们可以看一下源码
/**
* Creates a file output stream to write to the file represented by
* the specified <code>File</code> object. A new
* <code>FileDescriptor</code> object is created to represent this
* file connection.
* <p>
* First, if there is a security manager, its <code>checkWrite</code>
* method is called with the path represented by the <code>file</code>
* argument as its argument.
* <p>
* If the file exists but is a directory rather than a regular file, does
* not exist but cannot be created, or cannot be opened for any other
* reason then a <code>FileNotFoundException</code> is thrown.
*
* @param file the file to be opened for writing.
* @exception FileNotFoundException if the file exists but is a directory
* rather than a regular file, does not exist but cannot
* be created, or cannot be opened for any other reason
* @exception SecurityException if a security manager exists and its
* <code>checkWrite</code> method denies write access
* to the file.
* @see java.io.File#getPath()
* @see java.lang.SecurityException
* @see java.lang.SecurityManager#checkWrite(java.lang.String)
*/
public FileOutputStream(File file) throws FileNotFoundException {
this(file, false);
}
在这上面我们可以看到它另有一个默认的参数,为false,根据注解这个参数的意思其实是判断你对该文件的操作是继续往下面添加,还是重新擦掉重来。默认是擦掉重来。
另外pdf可能会很大,很大利用这种方式就是会发生问题,因为二进制流数组不够大,这时候可以使用分块上传,自行实现这里就不赘述了。