关于文件是UTF-8 bom编码格式文件,ftp本身读取是没有问题的,而且读取到的内容看上去也是没有问题的!!但我的需求是读取一个XML文件,读取到本地后需要在本地使用Document解析、取出所有节点。问题就出现在解析xml报文的时候报错,导致解析出来的内容为null。
后来发现还是报文内容问题,找了很多资料,最后发现可能是文件的编码格式问题,一般都是utf-8的文件,但是有些情况windows会生成utf-8 bom编码格式的文件,详细请自行百度utf-8和utf-8 bom的区别。
这里我写了个demo测试一下,主要是使用了 UnicodeInputStream 这个类 如图:
测试前代码:
测试后代码:
而前后代码比较的取出来的报文如图:
现在才知道,报文解析为什么解析不出来了,就是因为多个一个特殊字符,
对已这个特殊字符开始我是把这个报文取出来后直接字符串截取
解决办法1:
//如果是utf-8 bom 格式
if(strFileContext.substring(0,1).contains("\uFEFF")){
logger.info(">>>>>>>>>>>>>>>>接收的字符串是utf-8 bom" +
"编码格式的>>>>>>>>>>>>>>>>>>");
strFileContext = strFileContext.substring(1);
}
strFileContext就是读取到的文件内容,直接把开头截取掉,这样简单粗暴。。。
但是更好的办法是如图二处理方式:
private static void getFileUniCode(File file) {
try {
StringBuffer stringBuffer = new StringBuffer();
InputStream inputStream = new FileInputStream(file);
//主要是使用UnicodeInputStream类
UnicodeInputStream unicodeInputStream =
new UnicodeInputStream(inputStream,null);
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(unicodeInputStream));
String line = null;
//一行一行的读文件内容并拼接起来
while((line=bufferedReader.readLine()) != null){
stringBuffer.append(line);
}
//打印读取的文件内容
System.out.println(stringBuffer.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
这样就把文件内容开头的‘-’给去掉。
下面贴一下我ftp接收的报文代码:
public static String writeFile(FTPFile ff, String localpath, FTPClient ftp, Integer connectId) {
FileOutputStream out = null;
InputStream in = null;
UnicodeInputStream unicodeInputStream = null;
String outFileName = ff.getName();
try {
in = ftp.retrieveFileStream(new String(outFileName.getBytes("GB2312"),"ISO-8859-1"));
Thread.sleep(10);
if(in.available() > 0){
File localFile = new File(localpath.concat(File.separator).concat(outFileName ));
out = new FileOutputStream(localFile);
//对读取出来的流做处理,避免 utf-8 bom类似的文件
unicodeInputStream =
new UnicodeInputStream(in,null);
byte[] byteArray = new byte[4096];
int read = 0;
while ((read = unicodeInputStream.read(byteArray)) != -1) {
out.write(byteArray, 0, read);
out.flush();
}
out.close();
}
in.close();
unicodeInputStream.close();
// 要多次操作这个ftp的流的通道,要等他的每次命令完成
ftp.completePendingCommand();
} catch (Exception e) {
if (null != out) {
try {
out.close();
} catch (IOException ie) {
ie.printStackTrace();
}
}
if (null != in) {
try {
in.close();
} catch (IOException ie) {
ie.printStackTrace();
}
}
if(unicodeInputStream != null){
try {
unicodeInputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return strNewName;
}
共享文件夹读取代码
public static String writeFile(SmbFile smbFile, String localDir, Integer connectId) {
String outFileName = smbFile.getName();
FileOutputStream fos = null;
SmbFileInputStream smbs = null;
UnicodeInputStream unicodeInputStream = null;
try {
File localFile = new File(localDir.concat(File.separator).concat(outFileName ));
smbs = new SmbFileInputStream(smbFile);
unicodeInputStream =
new UnicodeInputStream(smbs,null);
byte[] b = new byte[1024];
fos = new FileOutputStream(localFile);
int index = 0;
while ((index = unicodeInputStream.read(b)) != -1) {
fos.write(b, 0, index);
fos.flush();
}
} catch (SmbException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (smbs != null) {
try {
smbs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(unicodeInputStream != null){
try {
unicodeInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return strNewName;
}
以上总结仅为个人经验,如果不对,请及时指出!!!