java 解析二进制文件保存为txt文件

java 解析二进制文件保存为txt文件
本文包含二进制解析,遍历文件夹下的文件,生成对应得文件夹以及文件,日期转换的知识点

import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.*;

/*
SL 二进制文件解析
 */
public class ReadSL {
    //阻塞队列线程安全
    private static BlockingQueue<File> queue = new LinkedBlockingQueue<File>(10000);
    //线程池
    private static ExecutorService threadPool = Executors.newFixedThreadPool(2);

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

        //监控线程
        threadPool.execute(new Runnable() {
            public void run() {

                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    int size = queue.size();
                    System.out.println("还有:" + size + "个元素");

                    threadPool.shutdown();

                }


            }
        });

        for (int i = 1; i <= 1; i++) {
            threadPool.execute(new Runnable() {
                public void run() {

                    while (true) {

                        try {
                            //从队列中获取文件
                            File file = queue.take();
                            parseText(file);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
        traverseFolder2("D:\\test");
    }

    //字节数组转单精度
    public static float  bytetofloat(byte[] b) {

        int accum = 0;
        accum = accum | (b[0] & 0xff) << 0;
        accum = accum | (b[1] & 0xff) << 8;
        accum = accum | (b[2] & 0xff) << 16;
        accum = accum | (b[3] & 0xff) << 24;

       float accumf= Float.intBitsToFloat(accum);
        BigDecimal bd = new BigDecimal(accumf);
        accumf= bd.setScale(6,BigDecimal.ROUND_HALF_UP).floatValue();
        return accumf;
    }

    //字节数组转int
    public static int bytetoInt(byte[] b) {
        int jd = 0;
        int jd0 = b[0] & 0xff;// 最低位
        int jd1 = b[1] & 0xff;
        int jd2 = b[2] & 0xff;
        int jd3 = b[3] & 0xff;
        jd3 <<= 24;
        jd2 <<= 16;
        jd1 <<= 8;
        jd = jd0 | jd1 | jd2 | jd3;
        return jd;
    }

    //时间转换
    public static String getDate(int t) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String historyTime = "1970-01-01 08:00:00";
        Date date = dateFormat.parse(historyTime);
        Date newDate = addSeconds(date, t);
        return dateFormat.format(newDate);
    }
    private static Date addSeconds(Date date, int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        return calendar.getTime();
    }


    public static void traverseFolder2(String path) throws Exception {

        //空文件夹处理
        File file = new File(path);
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files.length == 0) {
                return;
            } else {
                for (File file2 : files) {
                    if (file2.isDirectory()) {
                        traverseFolder2(file2.getAbsolutePath());
                    } else {
                        //将文件放入阻塞队列中
                        queue.put(file2);
                    }
                }
            }
        } else {
            System.out.println("文件不存在!");
        }
    }

    public static void parseText(File file) throws Exception {
        String result0 = null;
        //文件的路径
        File infile = new File(file.getAbsolutePath());
        //文件名称
        String name = infile.getName();
        //路径
        String absolutePath = infile.getAbsolutePath();
        //输入流
        InputStream bis = new FileInputStream(infile);
        //输出路径
        String outPath = "D:\\parseData";
        //切割文件路径
        String[] split = absolutePath.split("\\\\");
        byte[] b = new byte[1022];
        int len = 0;
        int count = 0;
        //txt文件暂不处理
        if (infile.getName().substring(name.length() - 4, name.length()).equals(".txt")) {
            return;
        } else {
            String time = "";
            long historyMillons = 0;
            String listStr = "";
            String listStr2="";
            ArrayList<String> list = new ArrayList<String>();
            //时间
            long historyTimeMillins=0;

            String path1 = "\\" + split[1] + "\\" + split[2] + "\\" + split[3] + "\\" + split[4] + "\\" + split[5] + "\\";
            outPath = outPath + path1 + infile.getName().substring(0, name.length() - 3) + ".txt";
            //创建文件
            createFiles(outPath);
            //输出流,追加写入文件
            BufferedWriter bw = new BufferedWriter(new FileWriter(outPath,true));
            //保留小数点后六位数字
            DecimalFormat format = new DecimalFormat("0.000000");
            while ((len = bis.read(b)) != -1) {
                count++;
                if (count == 1) {
                    //版本号
                    byte[] b1 = { b[1], b[2], b[3], b[4], b[5], b[6],b[7],b[8]};
                    //传感器类型简写
                    byte[] b2 = {b[9], b[10]};
                    //传感器类型全称
                    byte[] b3 = {b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]};
                    //时间
                    byte[] b4 = {b[20], b[21], b[22], b[23]};
                    //传感器编号
                    byte[] b5 = {b[25], b[26], b[27], b[28], b[29], b[30], b[31], b[32]};
                    String bbh = new String(b1, "UTF-8");
                    //System.out.println("版本号:" + bbh);
                    String jianXie = new String(b2, "UTF-8");

                    String fullName = new String(b3, "GBK");

                    //时间操作  字节数组转换long类型
                    long s0 = b4[0] & 0xff;// 最低位
                    long s1 = b4[1] & 0xff;
                    long s2 = b4[2] & 0xff;
                    long s3 = b4[3] & 0xff;
                    s1 <<= 8;
                    s2 <<= 16;
                    s3 <<= 24;
                    historyMillons = s0 | s1 | s2 | s3;
                    time = getDate((int) historyMillons);
                    // System.out.println("采集时间:" + time);

                    String bianHao = new String(b5, "utf-8");
                    //  System.out.println("传感器编号:" + bianHao);

                    //频率 单精度
                    byte[] b6 = {b[33], b[34], b[35], b[36]};
                    float pinLv = bytetofloat(b6);

                    //采样精度 32位整型
                    byte[] b7 = {b[37], b[38], b[39], b[40]};
                    int jingDu = bytetoInt(b7);
                    //放大倍数
                    byte[] b8 = {b[41], b[42], b[43], b[44]};
                    int beiShu = bytetoInt(b8);

                    //传感器灵敏度
                    byte[] b9 = {b[45], b[46], b[47], b[48]};
                    float minGanDu = bytetofloat(b9);
                    //文件头信息结束标志 $
                    //  byte[] b11 = {b[49]};
                    //System.out.println(new String(b11));
                    //文件头信息
                    result0 = bbh + "\t" + jianXie + "\t" + fullName + "\t" + time + "\t" + bianHao + "\t" + pinLv + "\t" + jingDu + "\t" + beiShu + "\t" + minGanDu + "\t";
                   //System.out.println(b.length);
                    //真正数据部分
                    for (int j = 50; j <= len - 4; j += 4) {
                        byte[] b12 = {b[j], b[j + 1], b[j + 2], b[j + 3]};
                        float cjsj = bytetofloat(b12);
                        String flToStr = String.valueOf(cjsj);
                        //取消科学计数法
                       flToStr= format.format(cjsj);
                        historyTimeMillins=historyMillons * 1000 + 50 * ((j - 50) / 4);
                        flToStr =  historyTimeMillins+ " " + flToStr;
                        list.add(flToStr);
                    }
                    b=new byte[102400*10];
                }
                else {
                    for (int i = 0; i < len - 3; i+=4) {
                        byte[] b13 = {b[i], b[i + 1], b[i + 2], b[i + 3]};
                        float cjsj = bytetofloat(b13);
                        //取消科学计数法
                        String format1 = format.format(cjsj);
                        format1= historyTimeMillins+ 50 * (i / 4) + " " + format1;
                        //System.out.println("采集数据:" + cjsj);

                        list.add(format1);
                        //listStr2 += flToStr + "\r\n";
                    }


                    }
            }

            //文件追加写入
            bw.write(result0+"\r\n");
            //System.out.println(list.size());
            for (int i =0;i<list.size();i++){
                //换行写入
                bw.write(list.get(i)+"\r\n");
            }
            bw.flush();
                bis.close();
                bw.close();
            }
        }

        public static void createFiles (String outPath) throws IOException {


            File outFile = new File(outPath);
            //输出路径
            File parentFile = outFile.getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }

            outFile.createNewFile();
        }

        public static void createDir (String outPath){
            File outFile = new File(outPath);
            //输出路径
            File parentFile = outFile.getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            outFile.mkdirs();
        }
    }
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值