类型转换
整形转化为字节数组
思路
int 1000
在电脑中的存储形式为:
0000 0000 0000 0000 0000 0011 1110 1000
转为字节数组为
arr[0] = 1110 1000 -> 10进制为-24(最前面一位是1说明他是负数,取反加一计算出它的十进制正值,就知道他的十负值)
arr[1] = 0000 0011 -> 10进制为3
arr[2] = 0000 0000 -> 10进制为0
arr[3] = 0000 0000 -> 10进制为0
代码实现
public static byte[] int2Bytes(int i){
//i的表现形式:0000 0000 0000 0000 0000 0011 1110 1000
byte[] arr = new byte[4];
//强转默认截掉前面的字节,保留最后一个字节
//强转截取后:1110 1000
arr[0] = (byte)i;
//右移8位,把第二个字节放到最后一个字节上,强转默认截掉前面的字节,保留最后一个字节
//右移8位:0000 0000 0000 0000 0000 0000 0000 0011
//强转截取后:0000 0011
arr[1] = (byte)(i >> 8);
arr[2] = (byte)(i >> 16);
arr[3] = (byte)(i >> 24);
return arr;
}
字节数组转化为整形
思路
int 1000
在电脑中的字节数组为:
0000 0000 0000 0000 0000 0011 1110 1000
转为字节数组为
arr[0] = 1110 1000 -> 10进制为-24(最前面一位是1说明他是负数,取反加一计算出它的十进制正值,就知道他的十负值)
arr[1] = 0000 0011 -> 10进制为3
arr[2] = 0000 0000 -> 10进制为0
arr[3] = 0000 0000 -> 10进制为0
字节数组里面有负值,需要把负值转换为正值,但要保证字节的存储形式没有变化,与上-1并转为int类型即可,并且要让对应的字节回到属于它原本的位置
代码实现
public static int Bytes2int(byte[] arr){
//与上-1并隐式转换为int后:0000 0000 0000 0000 0000 0000 1110 1000
int i0 = arr[0] & 0xFF;
//与上-1并隐式转换为int后:0000 0000 0000 0000 0000 0000 0000 0011
//左移8位后:0000 0000 0000 0000 0000 0011 0000 0000
int i1 = (arr[1] & 0xFF) << 8;
int i2 = (arr[2] & 0xFF) << 16;
int i3 = (arr[3] & 0xFF) << 24;
//或运算:
// 0000 0000 0000 0000 0000 0000 1110 1000
// 0000 0000 0000 0000 0000 0011 0000 0000
// 0000 0000 0000 0000 0000 0011 1110 1000(结果)
return i0 | i1 | i2 | i3;
}
归档
作用: 归档就是把多个文件塞到一个文件里面去
public static void main(String[] args) throws Exception {
Archiver archiver = new Archiver();
//归档是输出一个新的文件集合的过程,所以用输出流,如果以后想要一直往这个文件集合里塞东西,在参数里面再加个true
FileOutputStream fis = new FileOutputStream("D:\\aa\\arch\\pic.xar",true);
fis.write(archiver.arch("D:\\aa\\arch\\1.jpg"));
fis.write(archiver.arch("D:\\aa\\arch\\2.jpg"));
fis.write(archiver.arch("D:\\aa\\arch\\3.jpg"));
fis.write(archiver.arch("D:\\aa\\arch\\4.jpg"));
fis.write(archiver.arch("D:\\aa\\arch\\5.jpg"));
fis.write(archiver.arch("D:\\aa\\arch\\6.jpg"));
fis.close();
}
public byte[] arch(String path) throws Exception {
File file = new File(path);
//获取文件名
String fileName = file.getName();
//获取文件名的字节数组
byte[] fileNameBytes = fileName.getBytes();
//获取文件名长度的字节数组(整形转字节数组)
byte[] fileNameBytesLength = Util.int2Bytes(fileNameBytes.length);
//获取文件内容
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
//创建缓冲区
byte[] b = new byte[1024];
int len = 0;
while ((len = fis.read(b)) != -1){
bao.write(b,0,len);
}
fis.close();
byte[] fileContentBytes = bao.toByteArray();
//获取文件内容长度的字节数组
byte[] fileContentBytesLength = Util.int2Bytes(fileContentBytes.length);
//创建一个总字节数组
//需要存储的东西:
//1. 文件名的长度
//2. 文件名
//3. 文件内容的长度
//4. 文件内容
byte[] bytes = new byte[fileNameBytes.length + fileNameBytesLength.length + fileContentBytes.length + fileContentBytesLength.length];
//写入文件名长度字节数组
//参数:参数1:需要copy的数组A;参数2:copy的起始位置;参数3:存储的目标数组B;参数4:存储的起始位置;参数5:数组A存储的长度
System.arraycopy(fileNameBytesLength,0,bytes,0,fileNameBytesLength.length);
//写入文件名字节数组
System.arraycopy(fileNameBytes,0,bytes,fileNameBytesLength.length,fileNameBytes.length);
//写入文件内容长度字节数组
System.arraycopy(fileContentBytesLength,0,bytes,fileNameBytesLength.length + fileNameBytes.length,fileContentBytesLength.length);
//写入文件内容字节数组
System.arraycopy(fileContentBytes,0,bytes,fileNameBytesLength.length + fileNameBytes.length + fileContentBytesLength.length,fileContentBytes.length);
return bytes;
}
解档
作用: 把归档文件解出来成一个个独立的文件
public static void main(String[] args) throws Exception {
List<Map<String, Object>> maps = new ArrayList<>();
UnArchiver unArchiver = new UnArchiver();
File file = new File("D:\\aa\\arch\\pic.xar");
//解档需要读取归档文件,所以用输入流
FileInputStream fis = new FileInputStream(file);
Map<String, Object> map = null;
//因为归档文件不止一个所以要循环遍历,直到读不到为止
while ((map = unArchiver.readNextFile(fis)) != null){
maps.add(map);
}
fis.close();
//将归档文件遍历输出为一个个文件(解归档)
FileOutputStream fos = null;
for(Map<String, Object> map1:maps){
fos = new FileOutputStream("D:\\aa\\arch\\unarch\\" + map1.get("fileName"));
fos.write((byte[])map1.get("fileContent"));
fos.close();
}
}
public Map<String, Object> readNextFile(FileInputStream fis) throws Exception {
//读取文件名的长度(长度是int类型,占4个字节,所以读取4个字节的数组即可)
byte[] fileNameLengthBytes = new byte[4];
int res = fis.read(fileNameLengthBytes);
//如果读不到东西了,就要让程序停止
if(res == -1){
return null;
}
//将读到的字节数组转为整形就能得到文件名的长度,从而利用文件名的长度去读取文件名
int fileNameLength = Util.Bytes2int(fileNameLengthBytes);
//根据文件名的长度读取文件名
byte[] fileNameBytes = new byte[fileNameLength];
fis.read(fileNameBytes);
String fileName = new String(fileNameBytes);
//读取文件内容的长度
byte[] fileContentBytesLength = new byte[4];
fis.read(fileContentBytesLength);
int fileContentLength = Util.Bytes2int(fileContentBytesLength);
//根据文件内容的长度读取文件内容
byte[] fileContentBytes = new byte[fileContentLength];
fis.read(fileContentBytes);
Map<String, Object> map = new HashMap<String, Object>();
map.put("fileName",fileName);
map.put("fileContent",fileContentBytes);
return map;
}
压缩
作用: 压缩是归档的一种,但是他可以缩小文件的大小(不一定,如果这个文件太小,压缩后反而会变大)
public static void main(String[] args) throws Exception {
//压缩与归档一样需要输出一个新的文件集合,所以使用输出流
FileOutputStream fos = new FileOutputStream("D:\\aa\\arch\\pic.zip");
//将输出流封装成压缩输出流
ZipOutputStream zos = new ZipOutputStream(fos);
//需要压缩的文件路径集合
List<String> list = new ArrayList<>();
list.add("D:\\aa\\arch\\1.jpg");
list.add("D:\\aa\\arch\\2.jpg");
list.add("D:\\aa\\arch\\3.jpg");
list.add("D:\\aa\\arch\\4.jpg");
list.add("D:\\aa\\arch\\5.jpg");
list.add("D:\\aa\\arch\\6.jpg");
list.add("D:\\aa\\arch\\pic.xar");
list.add("D:\\aa\\arch\\ojdbc14.jar");
for(String url:list){
File file = new File(url);
//设置压缩的这个文件的名字(一般保持原本的名字即可)
zos.putNextEntry(new ZipEntry(file.getName()));
//获取压缩文件的内容
FileInputStream fis = new FileInputStream(file);
byte[] bytes = new byte[fis.available()];
fis.read(bytes);
fis.close();
//将压缩文件的内容写入压缩输出流中
zos.write(bytes);
}
zos.close();
fos.close();
}
解压缩
作用: 把压缩文件解出来成一个个独立的文件
public static void main(String[] args) throws Exception {
//解压缩跟解档一样需要对压缩文件处理,所以需要获取压缩文件的输入流
FileInputStream fis = new FileInputStream("D:\\aa\\arch\\pic.zip");
//将输入流包装成压缩输入流
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry zipEntry = null;
int len = 0;
byte[] bytes = new byte[1024];
//遍历读取压缩输入流文件直到不能再读
while ((zipEntry = zis.getNextEntry()) != null){
//获取文件的名字
String fileName = zipEntry.getName();
//将输入流文件的内容输出到单个文件中去
FileOutputStream fos = new FileOutputStream("D:\\aa\\arch\\pic\\" + fileName);
while ((len = zis.read(bytes)) != -1){
fos.write(bytes,0,len);
}
fos.close();
}
zis.close();
fis.close();
}