这个web api的接口是返回一个vcf的文件,文件中以END:VCARD和“\r\n”为结束符,后面的数据到文件末尾就是图片数据
首先,要以END:VCARD为结束符,就只能从中读取字符进行匹配,因为可能包含中文,所以我们暂且用read(char[])或者readLine()方法来实现,这样读出来的就是以字符或者整行为单位的,但是后面的数据要以byte的形式写入到图片文件中,所以这里我将输入流的数据copy了一份,具体见代码
try {
url = new URL(strUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoOutput(true);// post请求,需要向服务器写数据
connection.setDoInput(true);// 因为要从服务器端获取响应数据,所以为true(默认值也是true)
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type","multipart/form-data; boundary=" + boundary);
OutputStream outputStream = new DataOutputStream(
connection.getOutputStream());
// write first boundary
outputStream.write(("--" + boundary + "\r\n").getBytes());
// for(Map.Entry<String, String> entry : params.entrySet()) {
// outputStream.write(("Content-Disposition: from-data; name=\""
// +entry.getKey()+ "\"\r\n\r\n").getBytes());
// outputStream.write(entry.getValue().getBytes());
// outputStream.write(("\r\n--" + boundary + "\r\n").getBytes());
// }
outputStream
.write(("Content-Disposition: form-data; name=\"upfile\"; filename=\""
+ fileName + "\"\r\n").getBytes());
outputStream.write(("Content-type: application/octet-stream\r\n")
.getBytes());
outputStream.write("Content-Transfer-Encoding: binary\r\n\r\n"
.getBytes());
byte[] buffer = new byte[4096];
int length = 0;
while ((length = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
// write last boundary
outputStream.write(("\r\n--" + boundary + "--\r\n").getBytes());
outputStream.flush();
outputStream.close();
fileInputStream.close();
if (200 == connection.getResponseCode()) {
// 将图片数据结果写入到baos流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 保存图片信息
FileOutputStream fos = null;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
fos = new FileOutputStream(Environment
.getExternalStorageDirectory().getPath()
+ "/DCIM/result.jpg");
} else {
fos = new FileOutputStream(Environment.getDataDirectory()
.getPath() + "/sdcard/DCIM/Camera/result.jpg");
}
// 先将数据放入缓冲区,然后read的时候再冲缓冲区中取出数据(inputstream流的copy)
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
//先将inputstream中的数据全部读取到totalBaos输出流中
ByteArrayOutputStream totalBaos = new ByteArrayOutputStream();
byte[] totalBuffer = new byte[4096];
int l = 0;
while((l = bis.read(totalBuffer)) != -1) {
totalBaos.write(totalBuffer, 0, l);
}
totalBaos.flush();
bis.close();
//读取名片扫描的结果,文字部分
BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(totalBaos.toByteArray())));
StringBuffer strVcf = new StringBuffer();
String strTemp ;
while ((strTemp = br.readLine()) != null) {
strVcf.append(strTemp).append("\r\n");
if ( strVcf.toString().contains("END:VCARD")) {
Log.d("MainActivity", "strVcf length: "
+ strVcf.toString().getBytes().length + "");
// 当遇到结尾换行符时,同时整个串里面已经包含END:VCARD(之后的就是图片数据)
break;
}
}
br.close();
//写图片数据
byte[] picBuffer = new byte[2048];
int size = 0;
int total = 0;
bis = new BufferedInputStream(new ByteArrayInputStream(totalBaos.toByteArray()));
bis.skip(strVcf.toString().getBytes().length);//跳过文字部分的流数据
while ((size = bis.read(picBuffer)) != -1) {
// 保存图片数据到文件
fos.write(picBuffer, 0, size);
// 保存图片数据到baos流
baos.write(picBuffer, 0, size);
total += size;
Log.d("MainActivity", "total:" + total);
}
fos.flush();
fos.close();
baos.flush();
baos.close();
bis.close();
totalBaos.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
希望看到的人,提出自己的解决方法,我的这个方案感觉有点欠妥