java实现将二进制文件转换成字节文本,再将字节文本转换成二进制文件

一、说明

今天,项目现场提出这样一种需求:项目中,将项目文件打成zip包进行发布时,由于安全机制的限制,不允许发布二进制文件,因此需要将.zip格式的二进制文件encode成文本文件,再将文本文件上传后decode成.zip格式。

二、直接上代码

1、首先上传统IO实现方式

package com.mzj.pe.codec;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @Auther: mazhongjia
 * @Date: 2020/9/17 11:26
 * @Version: 1.0
 */
public interface BinaryTextCodec {

    String encode(FileInputStream fileInputStream) throws IOException;

    void decode(FileOutputStream outputStream, String text) throws IOException;

    public static BinaryTextCodec createBinaryTextCodec(){
        return new BinaryTextCodecImpl();
    }
}
package com..mzj.pe.codec;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @Auther: mazhongjia
 * @Date: 2020/9/17 11:28
 * @Version: 1.0
 */
public class BinaryTextCodecImpl implements BinaryTextCodec {

    private static final String TEXT_SPLIT_CHAR = ",";

    @Override
    public String encode(FileInputStream fileInputStream) throws IOException {
        if (fileInputStream == null) {
            return null;
        }
        StringBuilder builder = new StringBuilder();
        int i = 0;
        while ((i = fileInputStream.read()) != -1) {
            builder.append(i + TEXT_SPLIT_CHAR);
        }
        return builder.toString();
    }

    @Override
    public void decode(FileOutputStream fileOutputStream, String text) throws IOException {
        if (fileOutputStream == null || text == null) {
            return;
        }
        String[] lineone = text.split(TEXT_SPLIT_CHAR);

        for (int j = 0; j < lineone.length; j++) {
            fileOutputStream.write(Integer.valueOf(lineone[j]));
        }
        fileOutputStream.flush();
    }


}
package com.mzj.pe.codec;

import java.io.*;

/**
 * @Auther: mazhongjia
 * @Date: 2020/9/17 13:55
 * @Version: 1.0
 */
public class FileTransitionUtil {

    private static BinaryTextCodec binaryTextCodec = BinaryTextCodec.createBinaryTextCodec();

    public static void binaryToText(String binaryFilePath, String textFilePath) throws IOException {
        File binaryFile = new File(binaryFilePath);
        if (!binaryFile.exists()) {
            System.out.println("转换的二进制文件不存在....");
            return;
        }
        File textFile = new File(textFilePath);
        if (!textFile.exists())
            textFile.createNewFile();

        FileInputStream fileInputStream = null;
        BufferedWriter bufferedWriter = null;

        try {
            fileInputStream = new FileInputStream(binaryFile);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(textFile)));

            String encoder = binaryTextCodec.encode(fileInputStream);
            if (encoder != null) {
                bufferedWriter.write(encoder);
                bufferedWriter.flush();
                System.out.println("成功将【"+binaryFilePath+"】转换成文本文件【"+textFilePath+"】");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
            }
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
            }
        }
    }


    public static void textToBinary(String binaryFilePath, String textFilePath) throws IOException {
        File textFile = new File(textFilePath);
        if (!textFile.exists()) {
            System.out.println("转换的文本文件不存在....");
            return;
        }
        File binaryFile = new File(binaryFilePath);
        if (!binaryFile.exists())
            binaryFile.createNewFile();

        FileOutputStream fileOutputStream = null;
        BufferedReader bufferedReader = null;

        try {
            fileOutputStream = new FileOutputStream(binaryFile);
            bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(textFile)));

            binaryTextCodec.decode(fileOutputStream, bufferedReader.readLine());
            System.out.println("成功将【"+textFilePath+"】转换成二进制文件【"+binaryFilePath+"】");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
            }
        }
    }
}
package com.mzj.pe.codec;

import java.io.IOException;

/**
 * @Auther: mazhongjia
 * @Date: 2020/9/17 14:15
 * @Version: 1.0
 */
public class Demo {

    public static void main(String[] args) throws IOException {
        FileTransitionUtil.binaryToText("D:\\埃及项目画面说明.doc","D:\\1.txt");
        FileTransitionUtil.textToBinary("D:\\1.doc","D:\\1.txt");

        FileTransitionUtil.binaryToText("D:\\专题图演示视频.mp4","D:\\2.txt");
        FileTransitionUtil.textToBinary("D:\\2.mp4","D:\\2.txt");

        FileTransitionUtil.binaryToText("D:\\17年餐费未报销.zip","D:\\3.txt");
        FileTransitionUtil.textToBinary("D:\\3.zip","D:\\3.txt");


    }
}

2、然后我自己又用NIO实现了一版

package com.mzj.pe.codec.test;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * @Auther: mazhongjia
 * @Date: 2020/9/17 14:57
 * @Version: 1.0
 */
public class Text {

    public static void main(String[] args) throws Exception {

        Path pathIn = Paths.get("D://原始二进制文件.zip");
        Path pathOut = Paths.get("D://1.txt");

        FileChannel inputChannel = FileChannel.open(pathIn, StandardOpenOption.READ);
        FileChannel outputChannel =FileChannel.open(pathOut,StandardOpenOption.WRITE);

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        while (true){
            byteBuffer.clear();

            int read = inputChannel.read(byteBuffer);
            if(-1 == read){//此处用-1判断是否读完需要依赖上面的 byteBuffer.clear();
                //文件读完了
                break;
            }

            //读到文件中内容了,翻转缓冲区,准备get其中数据
            byteBuffer.flip();//本例中从ByteBuffer获取数据没有显示的get,而是将其作为参数传给另一个Channel的write方法,但是也是读其中的数据,所以也要进行翻转

            StringBuilder builder = new StringBuilder();
            while (byteBuffer.hasRemaining()){
                builder.append(byteBuffer.get()+",");//1、将bytebuffer中数据,以字节形式取出,每个字节后追加逗号,形成字符串,以便解析字符串时时按,分割还原字节
            }

            CharBuffer charBuffer = CharBuffer.allocate(builder.length());//2、定义一个上面生成字符串长度的ChatBuffer

            charBuffer.put(builder.toString());//3、将字符串写入CharBuffer(A,B,C,D....)
            charBuffer.flip();

            Charset charset= Charset.defaultCharset();//4、将CharBuffer数据准备写入outputChannel,写入之前,需要转换成ByteBuffer,转换时需要按照特定字符集编码形式进行转换
            ByteBuffer byteBuffe1r=charset.encode(charBuffer);
//            byteBuffe1r.flip();
            outputChannel.write(byteBuffe1r);//将byteBuffer中内容写入到Channel中//5、将CharBuffer的ByteBuffer数组写入outputChannel

//            outputChannel.write(byteTemp);//将byteBuffer中内容写入到Channel中
        }

        inputChannel.close();
        outputChannel.close();
    }
}

package com.mzj.pe.codec.test;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: mazhongjia
 * @Date: 2020/9/17 14:57
 * @Version: 1.0
 */
public class Text2 {

    public static void main(String[] args) throws Exception {

        Path pathIn = Paths.get("D://1.txt");
        Path pathOut = Paths.get("D://1.zip");

        FileChannel inputChannel = FileChannel.open(pathIn, StandardOpenOption.READ);
        FileChannel outputChannel =FileChannel.open(pathOut,StandardOpenOption.WRITE);

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        List<Byte> byteList = new ArrayList<>();
        while (true){
            byteBuffer.clear();

            int read = inputChannel.read(byteBuffer);
            if(-1 == read){//此处用-1判断是否读完需要依赖上面的 byteBuffer.clear();
                //文件读完了
                break;
            }

            //读到文件中内容了,翻转缓冲区,准备get其中数据
            byteBuffer.flip();//本例中从ByteBuffer获取数据没有显示的get,而是将其作为参数传给另一个Channel的write方法,但是也是读其中的数据,所以也要进行翻转

            while(byteBuffer.hasRemaining()){
                byteList.add(byteBuffer.get());
            }
        }
        byte[] bytes = new byte[byteList.size()];
        for (int ii=0;ii<bytes.length;ii++){
            bytes[ii] = byteList.get(ii);
        }

        //1、这里的data,是A,B,C...的字符串形式,也就是原始二进制文件的byte数组的字符串逗号分割形式
        String data = new String(bytes,Charset.defaultCharset());//这一步是通过文本的字节数组形式,获取文本内容//2、将文本文件中字节还原成A,B,C,....形式,这里相当于decode,解码字符集要与编码保持一致

        //3、下面是还原原二进制文件的字节数组:byte2s
        String[] dataspliet = data.split(",");
        byte[] byte2s = new byte[dataspliet.length];

        for (int ii=0;ii<byte2s.length;ii++){
            byte2s[ii] = Byte.valueOf(dataspliet[ii]);
        }

        //4、下面是根据原二进制文件字节数组封装ByteBuffer
        ByteBuffer byteBufferWrite = ByteBuffer.allocate(byte2s.length);

        byteBufferWrite.put(byte2s);

        byteBufferWrite.flip();
        //5、将字节数组写入outputChannel
        outputChannel.write(byteBufferWrite);//将byteBuffer中内容写入到Channel中

//            outputChannel.write(byteTemp);//将byteBuffer中内容写入到Channel中

        inputChannel.close();
        outputChannel.close();
    }
}

 

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值