谈过,文本转成十六进制,下面聊聊 。把转化成的文本,在回复到原先的内容。
常言道来而不往非礼也!
实现了上面一个功能,当然也要写一段程序恢复原先的文件了。不完成这个功能总觉的,不完整。
为了实现这个这个功能,当时呢,想到的办法是使用字符串的截取,解析,拼接等方法。
这段时间学习了正则表达式,发觉正则表示真实个好东西,在对字符串的处理上,感觉是太爽了。
先介绍一下,我的最早实现这个功能的代码
1,读取文件中的内容
2,根据内容进行截取一个字符串,只包含 “0xXX”字样字符串,然后进行解析。
3,重复2,动作,知道吧所有的内容解析出来
4,存到指定的文本中;
(题外话,我比较喜欢功夫熊猫中的几句话)
下面是我的代码:
[AppleScript] 纯文本查看 复制代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/*
* 把一个二进制文件转换成 文件
*
* */
public class ToFile {
public static void main(String[] args) throws IOException {
FileInputStream f = new FileInputStream("2.txt");
// 创建输入和输出流
InputStreamReader fis = new InputStreamReader(f);
FileOutputStream fos = new FileOutputStream("3.txt");
StringBuffer bf = new StringBuffer();
// 获取文件,解密文件
char[] ch = new char[2];
char[] chs = new char[1024];
int len = 0;
int index = 0;
while ((len = fis.read(chs)) != -1) {
// fos2.write(chs, 0, len);
if (len != 1024){
for (int x = len;x < 1024 ;x++) {
// 最后一次读取长度 一般会不足 1024 ,数组后面的数据没有清空,这样会造成,最后一次的数组再一次输出
chs[x]= '\u0000';
}
}
// 重新组合字符串
bf.append(chs);
// 判断是否包含指定的字符串
while ((index = bf.indexOf("0x")) != -1) {
// 排除读取 1024 字符的时候正好是 0x 结尾的这种可能
if (bf.length() >= 4) {
// 截取想要的 两个数字字符
ch = bf.substring(index + 2, index + 4).toCharArray();
// 写的时候定义了,定义了如果只有一位补 0
int x;
x = Integer.parseInt(String.valueOf(ch) , 16);
// System.out.print((char) x);
fos.write(x);
// 重新组合字符数组
bf.delete(0, index + 5);
} else {
// 字符长度 小于4 无法截取了
break;
}
}
}
// 释放资源
fis.close();
fos.close();
}
}
下面是我用正则表达式改进版本。
[AppleScript] 纯文本查看 复制代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* 把一个二进制文件转换成 文件
*
* */
public class ToFile2 {
public static void main(String[] args) throws IOException {
FileInputStream f = new FileInputStream("2.txt");
// 创建输入和输出流
InputStreamReader fis = new InputStreamReader(f);
FileOutputStream fos = new FileOutputStream("3.txt");
// 创建一个字符串
String str = new String();
// 获取文件,解密文件
char[] chs = new char[1024];
int len = 0;
while ((len = fis.read(chs)) != -1) {
// fos2.write(chs, 0, len);
if (len != 1024) {
for (int x = len; x < 1024; x++) {
// 最后一次读取长度 一般会不足 1024 ,数组后面的数据没有清空,这样会造成,最后一次的数组再一次输出
chs[x] = '\u0000';
}
}
// 把读取的内容拼接起来
// 去空格,防止最后一个是 空格
str = str.concat(String.valueOf(chs)).trim();
// 使用正则表达式,规则; 两边是边界, 0x 出现一次,后面两位是0-f大小写
String regex = "\\b[0][x][0-9A-Fa-f]{2}\\b";
// 把规则编译成模式
Pattern p = Pattern.compile(regex);
// 通过模式得到匹配器对象
Matcher m = p.matcher(str);
// 遍历得到索要的
while (m.find()) {
// System.out.println(m.group());
// 得到字符串 只包括 0xXX 的
String s = m.group();
// 截取字符串
String num = s.substring(2, 4);
// 解析字符串,转化成十六进制
int x = Integer.parseInt(num, 16);
// 写到文件中
fos.write(x);
}
// 如果最后一次出现 ,是为了防止 ,读取1024时候,正好读取到 0xXX的一部分
// 如果正好是1024字节,正好可以截取完成
if ((str.lastIndexOf("0x") == (str.length() - 4))
&& (str.lastIndexOf("0x") >= 4)) {
str = "";
} else {
// 否则没有截取到的
str = str.substring(str.lastIndexOf("0"));
}
}
// 释放资源
fis.close();
fos.close();
}
}
开始的时候并没有太注意正则表达式,在使用的时候时候,字符串 剪接,转化和使用正则表达式相比,正则表示方便了很多
正则表示确实的好使,程序变得简单多了。
|