黑马程序员技术交流社区

标题: 十六进制转文本 IO版本 [打印本页]

作者: L10052108    时间: 2016-11-6 18:47
标题: 十六进制转文本 IO版本
谈过,文本转成十六进制,下面聊聊 。把转化成的文本,在回复到原先的内容。
常言道来而不往非礼也!
[attach]134187[/attach]
实现了上面一个功能,当然也要写一段程序恢复原先的文件了。不完成这个功能总觉的,不完整。
为了实现这个这个功能,当时呢,想到的办法是使用字符串的截取,解析,拼接等方法。
这段时间学习了正则表达式,发觉正则表示真实个好东西,在对字符串的处理上,感觉是太爽了。

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

}

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



作者: 潘老板    时间: 2016-11-6 20:39
好像好厉害的样子·~
作者: hutujin    时间: 2016-11-6 20:42
大神我们做朋友吧

作者: L10052108    时间: 2016-11-7 20:08
hutujin 发表于 2016-11-6 20:42
大神我们做朋友吧

大神,称不上,呵呵,我还没有上基础班,只是花了一个月,看看风清扬,刘意的教学视屏。刚看完视屏没有几天,正准备上报名黑马就业班。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2