Java生成自己的软件才能读写的独特格式文件

来源:互联网 发布:淘宝模板 编辑:程序博客网 时间:2024/04/29 13:48

        可能大家曾经碰到过,有一些软件它的数据是一种独有的格式,比如酷狗音乐的歌词文件是KRC格式,漫画魔屏的漫画文件是MOSC格式的,你不能用一般的软件去打开它。这是一种只有它软件本身能够读写的文件,这样就能做到很好的保密效果。

       虽然我不能办到从上述的文件中提取我想要的东西出来,但是我根据我对这种做法的理解,我已经能够做到,让自己的软件读写自己独有的格式。

一、原理。

       原理很简单,这个得从计算机的基本概念开始说起。文件在计算机中的存储形式是二进制编码,常见的字符(标准英文字母和数字、英文符号)每一种在计算机中都有一个对应的二进制编码表示,即是ASCII码。例如数字1的ASCII码是49,而数字1在计算机中的存储表示为00110001。

       文件的基本单位是字节(byte),一个字节用8位二进制表示。因此,我用来生成独特格式的文件方法就是从字节方式来进行文件读写。

二、代码实现。

(1)文件合成:类似于文件压缩,但这里并没有使用压缩算法,只是将几个普通文件合成为一个特殊文件,即这里我所说的独特格式文件。

主要字节存储方式按下图结构:


public static String groupFolderPath = "F:\\FSD";public static String syntheticFilePath = "F:\\new.syn";


public static void synthesizeFiles() {    // 存放需要合成的多个文件的文件夹    File gfpFile = new File(groupFolderPath);    // 扫描文件夹    File[] cfs = gfpFile.listFiles();    File synFile = new File(syntheticFilePath);    try {        if (!synFile.exists()) {    synFile.createNewFile();}FileOutputStream fos = new FileOutputStream(synFile);DataOutputStream dos = new DataOutputStream(fos);dos.writeInt(cfs.length);dos.writeByte((byte) ' ');// 文件名存放String[] fns = new String[cfs.length];// 文件大小存放int[] fbtls = new int[cfs.length];// 文件字节byte[][] fbts = new byte[cfs.length][];for (int i = 0; i < cfs.length; i++) {    fns[i] = cfs[i].getName();    fbts[i] = getFileBytes(cfs[i]);    fbtls[i] = fbts[i].length;}for (int j = 0; j < fns.length; j++) {    // 以UTF-8编码写入字符串    dos.writeUTF(fns[j]);    dos.writeByte((byte) ',');    dos.writeInt(fbtls[j]);    dos.writeByte((byte) ' ');}for (int k = 0; k < fbts.length; k++) {    dos.write(fbts[k]);}System.out.println("文件合成成功,合成文件地址:" + syntheticFilePath);dos.close();fos.close();    } catch (IOException e) {e.printStackTrace();    }}

/** * 获得文件的字节码,以字节数组存储 *  * @param file *            需要的读取文件 * @return bytes * @throws IOException */public static byte[] getFileBytes(File file) throws IOException {    byte[] bytes = null;    FileInputStream fis = new FileInputStream(file);    DataInputStream dis = new DataInputStream(fis);    int le = dis.available();    bytes = new byte[le];    dis.read(bytes);    dis.close();    fis.close();    return bytes;}

(2)文件分解:类似于压缩文件解压,根据上述文件写入格式,读取相应位置数据,生成“解压”文件。

public static String decomposedFolderPath = "F:\\Decomposed";

public static void decomposeFile() {    File synFile = new File(syntheticFilePath);    try {        FileInputStream fis = new FileInputStream(synFile);DataInputStream dis = new DataInputStream(fis);// 读取文件个数int fileNum = dis.readInt();// 读取空格字符,并将光标向后移动dis.readByte();// 文件名存储String[] fns = new String[fileNum];// 文件大小存储int[] les = new int[fileNum];for (int i = 0; i < fileNum; i++) {    // 按UTF-8编码读取第i个文件的文件名    fns[i] = dis.readUTF();    // 读取字节,主要目的是将光标后移一字节    dis.readByte();    // 读取第i个文件的文件大小    les[i] = dis.readInt();    dis.readByte();}byte[][] bts = new byte[fileNum][];for (int j = 0; j < fileNum; j++) {    bts[j] = new byte[les[j]];    // 读取第j个文件的字节数据    dis.read(bts[j], 0, les[j]);}for (int k = 0; k < fileNum; k++) {    File df = new File(decomposedFolderPath + File.separator+ fns[k]);    if (!df.exists()) {File pf = df.getParentFile();if (!pf.exists()) {    pf.mkdirs();}df.createNewFile();    }    System.out.println("分解出文件【文件名:" + fns[k] + " , 大小 : " + les[k]+ "】");    writeFileBytes(df, bts[k]);}dis.close();fis.close();    } catch (FileNotFoundException e) {e.printStackTrace();    } catch (IOException e) {e.printStackTrace();    }}

/** * 向相应空白文件中写入字节数据 *  * @param file *            文件 * @param bytes *            需要写入的字节数据 * @throws IOException */public static void writeFileBytes(File file, byte[] bytes)throws IOException {    FileOutputStream fos = new FileOutputStream(file);    DataOutputStream dos = new DataOutputStream(fos);    dos.write(bytes);    dos.close();    fos.close();}

三、运行效果图。


       需要合成的文件:


        生成的特殊格式文件:


       分解特殊格式文件生成的文件:


四、总结。

       通过以上方法,即可成功生成特殊格式的文件,并且并非不可逆的,也就是说,不是合成了就乱了,还可以原封不动的还原,而且不会丢失数据。当然这只是提供了一种思路,生成自己的独特格式的时候,文件存储具体采用什么格式就看自己的需要了,这样就能让自己的数据的“藏”起来了。除非知道你的存储规律,否则是无法读取你的数据的。

       当然,这只能代表我个人的看法,如有雷同,纯属巧合。写得不好,欢迎大家批评指正。

0 0
原创粉丝点击