sms.vmsg文件是可以直接用Windows记事本打开的,打开后看到的内容格式如下
BEGIN:VMSG
VERSION:1.1
BEGIN:VCARD
TEL:10010
END:VCARD
BEGIN:VBODY
X-BOX:INBOX
X-READ:READ
X-SEEN:1
X-SIMID:0
X-LOCKED:UNLOCKED
X-TYPE:SMS
Date:2019/02/04 09:48:24
Subject;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:=E6=B7=B1=E5=9C=B3=E8=AD=A6=E6=96=B9=E6=8F=90=E7=A4=BA=EF=BC=9A=E5=85=A8=E5=B8=82=E7=A6=81=E5=94=AE=E3=80=81=E7=A6=81=E7=87=83=E3=80=81=E7=A6=81=E6=94=BE=E7=83=9F=E8=8A=B1=E7=88=86=E7=AB=B9=E3=80=82=E4=B8=BA=E7=BB=B4=E6=8A=A4=E5=85=AC=E5=85=B1=E5=AE=89=E5=85=A8=EF=BC=8C=E8=90=A5=E9=80=A0=E5=AE=89=E5=85=A8=E8=88=92=E9=80=82=E7=9A=84=E5=9F=8E=E5=B8=82=E7=8E=AF=E5=A2=83=EF=BC=8C=E8=AF=B7=E5=B9=BF=E5=A4=A7=E5=B8=82=E6=B0=91=E4=B8=8D=E8=B4=AD=E4=B9=B0=E3=80=81=E4=B8=8D=E5=82=A8=E5=AD=98=E3=80=81=E4=B8=8D=E7=87=83=E6=94=BE=E7=83=9F=E8=8A=B1=E7=88=86=E7=AB=B9=EF=BC=8C=E5=85=B1=E5=88=9B=E6=96=B0=E6=98=A5=E4=BD=B3=E8=8A=82=E5=B9=B3=E5=AE=89=E7=A5=A5=E5=92=8C=E3=80=82
END:VBODY
END:VMSG
你可能不认识,所以要使用以下代码进行转换,输出可读文字
sms,deliver, 10010,,,2019.02.04 09:48,16,深圳警方提示:全市禁售、禁燃、禁放烟花爆竹。为维护公共安全,营造安全舒适的城市环境,请广大市民不购买、不储存、不燃放烟花爆竹,共创新春佳节平安祥和。
ConvertMain.java
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class ConvertMain {
public static void main(String[] args) {
StringBuilder convertedString = new StringBuilder();
Map<String, Integer> map = new HashMap<String, Integer>();
int count = 1;
try {
Scanner scanner = new Scanner(new File("e:\\sms.vmsg"));
StringBuilder builder = new StringBuilder();
String str = new String();
Msg msg = new Msg();
do {
str = scanner.nextLine();
if (str.equals("BEGIN:VMSG")) {
builder.append("sms,");
} else if (str.startsWith("TEL")) {
// 加入TEL
msg.setTel(str.substring(4));
if (!map.keySet().contains(str.substring(4))) {
map.put(str.substring(4), count++);
}
} else if (str.startsWith("X-BOX")) {
// 加入投送方式
if (str.endsWith("INBOX")) {
msg.setX_box(2);
} else if (str.endsWith("SENDBOX")) {
msg.setX_box(3);
}
} else if (str.startsWith("Date")) {
// 加入日期
msg.setDate(str.substring(5).replaceAll("/", "\\.")
.substring(0, 16));
} else if (str.startsWith("Subject")) {
// 加入内容
StringBuilder builder2 = new StringBuilder();
builder2.append(str.substring(48));
String str1 = scanner.nextLine();
while (!str1.startsWith("END")) {
builder2.append(str1);
str1 = scanner.nextLine();
}
String source = builder2.toString().replaceAll("==", "=");
byte[] array = getBytes(source.toCharArray());
msg.setContent(QuotedPrintable.decode(array, "UTF-8")
.replaceAll("\\s+", ""));
}
if (msg.getContent() != null && msg.getDate() != null
&& msg.getTel() != null && msg.getX_box() != 0) {
if (msg.getX_box() == 2) {
// deliver + ",count"
builder.append("deliver, " + msg.getTel() + ",,,"
+ msg.getDate() + "," + map.get(msg.getTel())
+ "," + msg.getContent() + "\r");
} else if ((msg.getX_box() == 3)) {
// send
builder.append("submit,, " + msg.getTel() + ",,"
+ msg.getDate() + "," + map.get(msg.getTel())
+ "," + msg.getContent() + "\r");
}
convertedString.append(builder.toString());
System.out.println(builder.toString());
msg = new Msg();
builder = new StringBuilder();
}
} while (str != "" && str != null);
} catch (Exception e) {
}
System.out.println(convertedString);
}
private static byte[] getBytes(char[] chars) {
Charset cs = Charset.forName("UTF-8");
CharBuffer cb = CharBuffer.allocate(chars.length);
cb.put(chars);
cb.flip();
ByteBuffer bb = cs.encode(cb);
return bb.array();
}
/*// byte转char
private static char[] getChars(byte[] bytes) {
Charset cs = Charset.forName("UTF-8");
ByteBuffer bb = ByteBuffer.allocate(bytes.length);
bb.put(bytes);
bb.flip();
CharBuffer cb = cs.decode(bb);
return cb.array();
}*/
}
Msg.java
public class Msg {
private String tel;
private int x_box;
private String date;
private String content;
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public int getX_box() {
return x_box;
}
public void setX_box(int x_box) {
this.x_box = x_box;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
QuotedPrintable.java
import java.io.UnsupportedEncodingException;
public class QuotedPrintable {
private final static byte TAB = 0x09; // /t
private final static byte LF = 0x0A; // /n
private final static byte CR = 0x0D; // /r
//private final static byte SPACE = 0x20; // ' '
private final static byte EQUALS = 0x3D; // '='
private final static byte LIT_START = 0x21;
private final static byte LIT_END = 0x7e;
private final static int MAX_LINE_LENGTH = 76;
private static int mCurrentLineLength = 0;
/**
* A method to decode quoted printable encoded data.
* It overrides the same input byte array to save memory. Can be done
* because the result is surely smaller than the input.
*
* @param qp
* a byte array to decode.
* @return the length of the decoded array.
*/
public static int decode(byte [] qp) {
int qplen = qp.length;
int retlen = 0;
for (int i=0; i < qplen; i++) {
// Handle encoded chars
if (qp[i] == '=') {
if (qplen - i > 2) {
// The sequence can be complete, check it
if (qp[i+1] == CR && qp[i+2] == LF) {
// soft line break, ignore it
i += 2;
continue;
} else if (isHexDigit(qp[i+1]) && isHexDigit(qp[i+2]) ) {
// convert the number into an integer, taking
// the ascii digits stored in the array.
qp[retlen++]=(byte)(getHexValue(qp[i+1])*16
+ getHexValue(qp[i+2]));
i += 2;
continue;
} else {
System.out.println("decode: Invalid sequence = " + qp[i+1] + qp[i+2]);
}
}
// In all wrong cases leave the original bytes
// (see RFC 2045). They can be incomplete sequence,
// or a '=' followed by non hex digit.
}
// RFC 2045 says to exclude control characters mistakenly
// present (unencoded) in the encoded stream.
// As an exception, we keep unencoded tabs (0x09)
if( (qp[i] >= 0x20 && qp[i] <= 0x7f) ||
qp[i] == TAB || qp[i] == CR || qp[i] == LF) {
qp[retlen++] = qp[i];
}
}
return retlen;
}
private static boolean isHexDigit(byte b) {
return ( (b>=0x30 && b<=0x39) || (b>=0x41&&b<=0x46) );
}
private static byte getHexValue(byte b) {
return (byte)Character.digit((char)b, 16);
}
/**
*
* @param qp Byte array to decode
* @param enc The character encoding of the returned string
* @return The decoded string.
*/
public static String decode(byte[] qp, String enc) {
int len=decode(qp);
try {
return new String(qp, 0, len, enc);
} catch (UnsupportedEncodingException e) {
return new String(qp, 0, len);
}
}
/**
* A method to encode data in quoted printable
*
* @param content
* The string to be encoded
* @param enc
* The character encoding of the content string
* @return The encoded string. If the content is null, return null.
*/
public static String encode(String content, String enc) {
if (content == null)
return null;
byte[] str = null;
try {
str = content.getBytes(enc);
} catch (UnsupportedEncodingException e) {
str = content.getBytes();
}
return encode(str);
}
/**
* A method to encode data in quoted printable
*
* @param content
* The byte array of the string to be encoded
* @return The encoded string. If the content is null, return null.
*/
public static String encode(byte[] content) {
if (content == null)
return null;
StringBuilder out = new StringBuilder();
mCurrentLineLength = 0;
int requiredLength = 0;
for (int index = 0; index < content.length; index++) {
byte c = content[index];
if (c >= LIT_START && c <= LIT_END && c != EQUALS) {
requiredLength = 1;
checkLineLength(requiredLength, out);
out.append((char)c);
} else {
requiredLength = 3;
checkLineLength(requiredLength, out);
out.append('=');
out.append(String.format("%02X", c));
}
}
return out.toString();
}
private static void checkLineLength(int required, StringBuilder out) {
if (required + mCurrentLineLength > MAX_LINE_LENGTH - 1) {
out.append("=/r/n");
mCurrentLineLength = required;
} else
mCurrentLineLength += required;
}
}