A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© L10052108 中级黑马   /  2016-11-6 18:47  /  1554 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

谈过,文本转成十六进制,下面聊聊 。把转化成的文本,在回复到原先的内容。
常言道来而不往非礼也!

实现了上面一个功能,当然也要写一段程序恢复原先的文件了。不完成这个功能总觉的,不完整。
为了实现这个这个功能,当时呢,想到的办法是使用字符串的截取,解析,拼接等方法。
这段时间学习了正则表达式,发觉正则表示真实个好东西,在对字符串的处理上,感觉是太爽了。

先介绍一下,我的最早实现这个功能的代码
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();
	}

}

开始的时候并没有太注意正则表达式,在使用的时候时候,字符串 剪接,转化和使用正则表达式相比,正则表示方便了很多
正则表示确实的好使,程序变得简单多了。


3 个回复

倒序浏览
好像好厉害的样子·~
回复 使用道具 举报
回复 使用道具 举报
hutujin 发表于 2016-11-6 20:42
大神我们做朋友吧

大神,称不上,呵呵,我还没有上基础班,只是花了一个月,看看风清扬,刘意的教学视屏。刚看完视屏没有几天,正准备上报名黑马就业班。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马