日期:2014-05-20  浏览次数:20880 次

再次求助将十六进制文件转成十进制
本帖最后由 u014301433 于 2014-04-09 15:24:45 编辑
之前问题描述不够清楚,今天再发一个帖子。主要就是想把一个十六进制文本文件转换成十进制的CSV文件。
在本地D盘上有一个以十六进制存储的文本文件。此文件包含了很多个数据块,每个数据块在实际业务中是同一个ID下的多条记录(每条记录的字段都是一样的)。每个数据块都是以四个FF开始作为标识。用UE打开如下所示:


第一行是文件头信息,这个数据不需要,直接过滤掉即可。

以FF FF FF FF开头的每个数据块包含九个字段的数据内容。分别是ID、IDName、Date、Item01、Item02、Item03、Item04、Item05、Item06。其中,ID和IDName字段的数据只在每个数据块中的第一行和第二行出现一次,后面的七个字段内容是多次出现,即每两行一条记录,代表具体某一天的数据记录情况。

举第一个数据块为例:

ID            ——53 48 36 30 30 30 30 30,用八个进制符位来表示,这个要转换成十进制的字符串。
IDName ——C6 D6 B7 A2 D2 F8 D0 D0,这个字段内容也是用八个进制符位来表示,这个也要转换成十进制的字符串。

注:每个数据块的第一行和第二行,只有上面16个进制符位的数据有用,这两行中剩余的其他16个进制符位数据不需要,直接跳过。

Date       ——80 01 3A 53,这个日期字段的内容需要反向读取(即53 3A 01 80)来转换成十进制整型。它是以毫秒存储的,需要转换成短日期型,即不包含时间的日期(比如20140403)。
Item01   ——5C 8F 1A 41,这个字段内容需要转换成十进制浮点型,也是反向读取。
Item02   ——A4 70 1D 41,也是转换成十进制浮点型,反向读取。
Item03   ——7B 14 1A 41,转换成十进制浮点型,反向读取。
Item04   ——14 AE 1B 41,转换成十进制浮点型,反向读取。
Item05   ——F0 E0 93 49,转换成十进制浮点型,反向读取。
Item06  ——BA 69 8C 4E,转换成十进制浮点型,反向读取。


这个数据块内剩余的数据都是每两行为一条记录,重复上面Date到Item06这个七个字段的内容。
另外,上面的这九个字段的内容,除了ID和IDName两个字段的内容进行读取时不需要反向读取,其他均需要反向读取,然后转换成要求的不同数据类型的十进制数据。

我需要的就是按上面这样将十六进制的文本文件转换成含不同数据类型的十进制的CSV文件。



------解决方案--------------------
引用:
Quote: 引用:

日期字段转换的不正确。都是“19700117”,字段少了一个Item06。


就不能自己改改,处理下,送佛得还得送上西;
那个日期做了处理的话,你得还原,也不清楚你原来是怎么处理,这就是简单*1000了;


import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class HexParser {

static Calendar cal = Calendar.getInstance();
static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

static String fileFullPath = "E:/SUPERSTK.DAD";//Change it to the actual file path

public static void main(String[] args) {
try {
readHexFile();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void readHexFile()throws Exception{
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(fileFullPath)));
in.skipBytes(16);

byte[] bytes = new byte[16];
int nCounts = 0;

while((in.read(bytes)) != -1){
String hexStr = toStringHex(bytes[0]) + toStringHex(bytes[1]) 
+ toStringHex(bytes[2]) + toStringHex(bytes[3]);
if(hexStr.equalsIgnoreCase("FFFFFFFF")){
nCounts = 1;
}else{
nCounts++;
}

if(nCounts > 2){
getDateAndItemx(bytes, nCounts);
}else{
getIDAndIDName(bytes, nCounts);
}
}

in.close();
}


private static void getIDAndIDName(byte[] bytes, int nCounts) {
if(nCounts == 1){
System.out.print("ID: " + new String(bytes, 4, 8));
System.out.print(", ");
}else{
System.out.print("IDName: " + new String(bytes, 4, 8, Charset.forName("GBK")));
System.out.print(": ");
System.out.println();
}

}


private static void getDateAndItemx(byte[] bytes, int nCounts) {
if(nCounts%2 == 0){
getItemX(bytes, 0, 4, 4);
getItemX(bytes, 4, 4, 5);
getItemX(bytes, 8, 4, 6);
System.out.println();
}else{
getDate(bytes);
getItemX(bytes, 4, 4, 1);
getItemX(bytes, 8, 4, 2);
getItemX(bytes, 12, 4, 3);
}
}

private static String getItemX(byte[] bytes, int start, int length, int itemIndex) {
StringBuilder hexStr = new StringBuilder();
for(int i = start + length - 1 ; i >= start; i--){
hexStr.append(toStringHex(bytes[i]));
}
System.out.print("Item0" + itemIndex + ": " + hexStr.toString().toUpperCase());
System.out.print(", ");

return hexStr.toString();
}


private static String getDate(byte[] bytes){
String hexStr = toStringHex(bytes[3]) + toStringHex(bytes[2])
        + toStringHex(bytes[1]) + toStringHex(bytes[0]);
cal.setTimeInMillis(((long)Integer.parseInt(hexStr, 16))*1000);
System.out.print("Date: " + sdf.format(cal.getTime()));