概述
起因:在使用Selenium实现截图时,发现API有三种方式生成截图:
byte[] img = driver.getScreenshotAs(OutputType.BYTES);
String img = driver.getScreenshotAs(OutputType.BASE64);
File img = driver.getScreenshotAs(OutputType.FILE);
这三种方式有什么区别?我应该用哪一种?
事实上,在之前的开发生涯中,也断断续续会遇到这三种数据类型之间的互转化的需求。每次都是临时Google搜索,于是本文记录整理一下,也算是一个备忘录。
实现
String与byte[]相互转化
这个基本上是最简单的,不需要Google搜索:
// String to byte[]
// 无传参, 默认UTF-8
byte[] a1 = "ss".getBytes();
// 指定Charset,IDEA会提示用第四种写法
byte[] a2 = s.getBytes(Charset.defaultCharset());
// string指定Charset,会抛异常UnsupportedEncodingException,需捕获,IDEA会提示用第四种写法
byte[] a3 = s.getBytes("utf-8");
// 推荐
byte[] a4 = s.getBytes(StandardCharsets.UTF_8);
// byte[] to String
Arrays.toString(a1);
String与File相互转化
File to String
读取File,获取其文件流
@Slf4j
public static String fileToBase64(File file) {
String base64 = null;
InputStream in = null;
try {
in = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
in.read(bytes);
base64 = Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
log.error("fileToBase64 failed: ", e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
log.error("fileToBase64 close in failed: ", e);
}
}
}
return base64;
}
String to File
将String形式的字符流转化为File文件:
@Slf4j
public static void base64ToFile(String destPath, String base64, String fileName) {
File file;
// 创建文件目录
File dir = new File(destPath);
if (!dir.exists() && !dir.isDirectory()) {
dir.mkdirs();
}
BufferedOutputStream bos = null;
java.io.FileOutputStream fos = null;
try {
byte[] bytes = Base64.getDecoder().decode(base64);
file = new File(destPath + "/" + fileName);
fos = new java.io.FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bytes);
} catch (Exception e) {
log.error("base64ToFile failed: ", e);
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
log.error("base64ToFile close bos failed: ", e);
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
log.error("base64ToFile close fos failed: ", e);
}
}
}
}
byte[]与File相互转化
byte[] to File
public static void byte2File(byte[] buf, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file;
try {
File dir = new File(filePath);
if (!dir.exists() && dir.isDirectory()) {
dir.mkdirs();
}
file = new File(filePath + File.separator + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(buf);
} catch (Exception e) {
log.error("byte2File failed: ", e);
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
log.error("byte2File close bos failed: ", e);
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
log.error("byte2File close fos failed: ", e);
}
}
}
}
File to byte[]
public static byte[] file2byte(File file) {
byte[] buffer = null;
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
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();
} catch (IOException e) {
log.error("file2byte failed: ", e);
}
return buffer;
}
File和MultipartFile相互转化
File转换成MultipartFile
直接给出解决方案,需引入依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
实现代码:
FileInputStream fileInputStream = new FileInputStream(file);
// contentType根据需求调整
MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(), ContentType.IMAGE_PNG.toString(), fileInputStream);
由于MultipartFile是一个接口,不能实例化,故而借助于spring-test
提供的MockMultipartFile来实例化。
MockMultipartFile源码如下:
public class MockMultipartFile implements MultipartFile {
private final String name;
private String originalFilename;
@Nullable
private String contentType;
private final byte[] content;
public MockMultipartFile(String name, @Nullable byte[] content) {
this(name, "", (String)null, (byte[])content);
}
public MockMultipartFile(String name, InputStream contentStream) throws IOException {
this(name, "", (String)null, (byte[])FileCopyUtils.copyToByteArray(contentStream));
}
public MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) {
Assert.hasLength(name, "Name must not be null");
this.name = name;
this.originalFilename = originalFilename != null ? originalFilename : "";
this.contentType = contentType;
this.content = content != null ? content : new byte[0];
}
public MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream) throws IOException {
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
}
提供4种实例化方式,最终都是通过byte[]
字节流来实现。
其中File转化为byte[]
使用spring-core
自带的FileCopyUtils工具类。
MultipartFile转换成File
需要引入依赖:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
代码:
File file = new File(path);
FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
结论
spring-core,包括其他commons-utils已经提供很多实现好的工具类,而且是经过若干用户验证的,几乎没有问题的代码。
建议不要花精力重复写工具类方法,更不要用于生产项目,不过还是可以自己手写代码模仿及学习。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/142226.html