如果文件中含有中文字符,那么这时候直接进行读取,即new FileInputStream(要读取的文件)
,就会出现了乱码,所以这时候,我们需要设置对应的格式进行读取,所以还需要传递对应的编码,所以将代码改成下面那样:new InputStreamReader(new FileInputStream(要读取的文件),"utf-8")
,那么就不会再发生乱码了.
同时,如果需要利用java来解析vcf文件,那么需要设置调用相关的方法来进行编码和解码,这个编码和解码的方式网上也有,可以自行百度的,这里主要来说,将对应的信息写入到.vcf文件需要注意的地方:
- 利用FileWriter对象来写入文件中的时候,需要注意进行刷新,否则,当程序结束的时候,文件可能什么数据都没有
- 如果写入的数据还有中文数据,那么记得要调用对应的方法来进行编码,否则对应的.vcf文件就是乱码的
- 写入的数据不需要以分号结束
所以对应的代码为:
package service;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import entity.Person;
public class VCFService {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
VCFService service = new VCFService();
File file = new File("src/a.vcf");
FileInputStream fis = new FileInputStream(file);
List<Person> persons = service.importVCF(fis);
File des = new File("src/b.vcf");
if(!des.exists()) {
des.createNewFile();
}
service.exportVCF(persons,des);
}
private void exportVCF(List<Person> persons,File des) throws Exception {
/*
* vcf文件:
* 格式为:
* 1、以BEGIN:VCARD开始
* 2、说明版本:VERSION:3.0
* 3、N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE: -->说明名字
* 4、FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE -->说明英文名字
* 5、TEL;TYPE=CELL: --> 说明电话
* 6、EMAIL: -->说明邮箱
* 7、END:VCARD
*/
FileWriter w = new FileWriter(des);
for(Person person: persons) {
addToVcf(person,w);
}
w.close();//关闭之前会自动刷新
}
public void addToVcf(Person person,FileWriter w) throws Exception {
//注意不要有分号,否则,导入到手机的形式将会是它的编码形式,不是中文的形式出现
//同时不可以直接将person.getName()输入到文件中,否则会出现乱码,需要进行编码
w.write("BEGIN:VCARD\r\n");
w.write("VERSION:3.0\r\n");
w.write("N;CHARSET=UTF-8:" + encode(person.getName()) + "\r\n");
w.write("FN;CHARSET=UTF-8:" + encode(person.getName())+ "\r\n");
w.write("TEL;TYPE=CELL:" + encode(person.getCell()) + "\r\n");
w.write("EMAIL:" + encode(person.getEmail()) + "\r\n");
w.write("END:VCARD\r\n");
w.flush();
}
public String decoding(String str) throws UnsupportedEncodingException {
if(str == null) {
return "";
}
str = str.trim();
str = str.replaceAll("=\n","");
byte[] bytes = str.getBytes("US-ASCII");
if(bytes == null) {
return "";
}
for(int i = 0; i < bytes.length; ++i) {
if(bytes[i] == 95) {
bytes[i] = 32;
}
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
for(int i = 0; i < bytes.length; ++i) {
if(bytes[i] == '=') {
if(i + 2 >= bytes.length) {
break;
}
int l = Character.digit((char)bytes[++i], 16);
int r = Character.digit((char)bytes[++i], 16);
if(l == -1 || r == -1) {
continue;
}
buffer.write((char)((l << 4) + r));
}else {
buffer.write(bytes[i]);
}
}
return new String(buffer.toByteArray(),"UTF-8");
}
public List<Person> importVCF(FileInputStream file) throws Exception {
//导入对应的vcf文件
//需要保证这个是utf-8,否则读取文件的时候发生了乱码
BufferedReader bfr = new BufferedReader(new InputStreamReader(file,"utf-8"));
String line = null;
ArrayList<Person> persons = new ArrayList<>();
List<String> names = new ArrayList<>();
List<String> cells = new ArrayList<>();
List<String> emails = new ArrayList<>();
while((line = bfr.readLine()) != null) {
System.out.print(line);
int index = line.indexOf(":");//获取第一个冒号的下标,冒号后面就是他的值
//获取姓名和电话
if(line.startsWith("N;CHARSET=UTF-8:")) {
//这时候需要获取它的名字,名字有被进行编码过,所以需要解码
/*
并不是对整个line进行解码,而是对它的值进行解码,因为
CHARSET=UTF-8中同样含有‘=’号,如果对整个line进行解
码的话,那么就会影响到了CHARSET=UTF-8,从而没有办法
获取数据的值了
*/
line = decoding(line.substring(index + 1));
names.add(line);
}else if(line.startsWith("TEL;TYPE=CELL:")) {
//因为电话,邮箱等不是中文,所以不需要进行解码就可以得到
line = line.substring(index + 1);
cells.add(line);
}else if(line.startsWith("EMAIL:")) {
line = line.substring(index + 1);
emails.add(line);
}
}
int size = names.size();
for(int i = 0; i < size; ++i) {
persons.add(new Person(names.get(i),cells.get(i),emails.get(i)));
}
for(Person person: persons) {
System.out.println(person);
}
return persons;
}
public String encode(String str) throws Exception {
if (str != null) {
char[] encode = str.toCharArray();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < encode.length; i++) {
if ((encode[i] >= '!') && (encode[i] <= '~')
&& (encode[i] != '=') && (encode[i] != '\n')) {
sb.append(encode[i]);
} else if (encode[i] == '=') {
sb.append("=3D");
} else if (encode[i] == '\n') {
sb.append("\n");
} else {
StringBuffer sbother = new StringBuffer();
sbother.append(encode[i]);
String ss = sbother.toString();
byte[] buf = null;
buf = ss.getBytes("utf-8");
// UTF-8: buf.length == 3
// GBK: buf.length == 2
if (buf.length == 3) {
for (int j = 0; j < buf.length; j++) {
String s16 = String.valueOf(Integer
.toHexString(buf[j]));
char c16_6;
char c16_7;
if (s16.charAt(6) >= 97 && s16.charAt(6) <= 122) {
c16_6 = (char) (s16.charAt(6) - 32);
} else {
c16_6 = s16.charAt(6);
}
if (s16.charAt(7) >= 97 && s16.charAt(7) <= 122) {
c16_7 = (char) (s16.charAt(7) - 32);
} else {
c16_7 = s16.charAt(7);
}
sb.append("=" + c16_6 + c16_7);
}
}
}
}
str = sb.toString();
}
return str;
}
}
当生成了.vcf文件之后,我们可以将其发送到手机,然后利用电话来打开对应的文件,那么之后就可以发现我们定义的联系人的信息了。