目的:为什么要文件转字符串?
程序进行tcp/ip socket通讯时,通讯内容一般都转换成byte数组型。
对读取声音、图像、视频等文件时,在Java中一般以字节流的形式读取为一个byte数组。
但是如果我们要对数据进行加密时,byte数组没有字符串加密来的轻松,因此这里的需求是把byte[]数组转换为字符串,再把字符串转换为正常的byte[]数组,转换为byte[]数组后,想要再转换为文件,就轻松多了。
第一步:文件转为byte数组
在这一步很多方法,这里采取一种最简单粗暴的,并且为了代码整齐,选择了抛出异常。
- 前置知识:字节流
public static void main(String[] args) throws Exception{
File file = new File("文件的路径");
FileInputStream fileInputStream = new FileInputStream(file);
int size = fileInputStream.available();
byte[] buffer = new byte[size];
fileInputStream.read(buffer);
fileInputStream.close();
}
这个方法如果加载的是一些大文件,size很容易导致内存不够,严谨地做法应该是1024个字节、1024个字节地读。
第二步:byte数组转换为字符串
这个地方有个很容易错误的点,博主在这里踩了个坑,因此记录下这篇博客,希望路过的博友们避免这个错误。
首先,byte数组不容易通过JDK提供的方法转换为字符串,所以我们一般用char数组来转换为字符串。
byte数组转换为char数组有很多种方法。
这边提供一种比较直接的做法,就是直接转。
为什么可以直接转?
- byte在Java中是8个位,1个字节来存储的
- char在Java中是16个位,2个字节来存储的
- 从低位转高位,是不会出现二进制截断的问题
- 后面需要把char强转回来byte,是从高位向低位转换,但是由于本身的值就是从byte转过来的,因此char转byte也不会出现数据溢出或数据丢失的问题,在这里是可以这么转的,但不保证其他情况,具体情况具体分析。
char[] byToChs = new char[size];
for(int i =0;i<size;i++){
byToChs[i] = (char) buffer[i];
}
直接使用toString()吗?
那么问题来了,char[] 转换成字符串,是直接使用toString()吗?
String str = byToChs.toString();
我们先来看一下输出的字符串
看到这里,应该博友们都知道答案了。
在这里,绝对不能使用toString()
在这里,博主当时就想当然地继续往下写代码了,下意识地认为toString就是把字符数组转换为字符串。
在Java中,对字符数组使用Object的方法toString,输出的字符串是字符数组的内存地址,而不是字符数组转换为字符串。
只要避免了这个坑,剩下的问题就很简单了。
同样的,这里有很多种字符数组转换为字符串的方式,这边博主还是用比较简单粗暴的方法来进行转换。
StringBuilder sb = new StringBuilder();
sb.append(byToChs);
String str = sb.toString();
我们来输出看一下这个字符串是什么
可以看出这个文件是个PNG文件,剩下的都是乱码,这都是非常正常的现象,到此,文件以及成功转换为字符串了。
剩下的就是把字符串反向转换为文件了。
这个操作跟上面的操作是反过来的,在这里就不再赘述了,直接把代码放出来。
public static void main(String[] args) throws Exception{
//1、第一步:文件转为byte数组
File file = new File("文件路径");
FileInputStream fileInputStream = new FileInputStream(file);
int size = fileInputStream.available();
byte[] buffer = new byte[size];
fileInputStream.read(buffer);
//2、第二步:byte数组转换为char数组
char[] byToChs = new char[size];
for(int i =0;i<size;i++){
byToChs[i] = (char) buffer[i];
}
//3、第三步:char数组转换为字符串
StringBuilder sb = new StringBuilder();
sb.append(byToChs);
String str = sb.toString();
//4、第四步:字符串转换为char数组
char[] strTochs = str.toCharArray();
//5、第五步:char数组转换为byte数组
for(int i = 0;i<size;i++){
buffer[i] = (byte) strTochs[i];
}
//6、第6步,把byte数组转化为文件
File outputFile = new File("文件路径");
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
fileOutputStream.write(buffer);
fileOutputStream.close();
fileInputStream.close();
}