我必须从包含以下内容的网址下载文件:
https://www.k4health.org/sites/default/files/প্রসব জনতি ফিস্টুলা চিহ্নিত করার চেকলিস্ট H11.pdf
我在编写URL之前尝试编码文件名,但它不起作用。该文件在我的SD卡中创建,但是有0个字节。这是我尝试的方式:
public String saveResourcesToSDCard(Resource res) {
String filepath = null;
String respath = "/bccp/" + bookID + "/resources/";
StringBuilder sb = new StringBuilder();
try {
sb.append(Constant.RESOURCE_FTP);
sb.append(new String(res.filename.getBytes(),"UTF-8"));
URL url = new URL(sb.toString());
//URL url = new URL(res.res_url);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
if(createDirIfNotExists(respath)){
String filename = new String(res.filename.getBytes(),"UTF-8");
Log.v("Local filename:", " " + filename);
File file = new File(SDCardRoot, filename);
if (file.createNewFile()) {
file.createNewFile();
}
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
int totalSize = urlConnection.getContentLength();
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
Log.v("Progress:", "DownloadedSize: " + downloadedSize
+ " TotalSize: " + totalSize);
}
fileOutput.close();
if (downloadedSize == totalSize){
filepath = file.getPath();
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
restartTask();
} catch (IOException e) {
filepath = null;
restartTask();
e.printStackTrace();
}
Log.v("filepath:", " " + filepath);
return filepath;
}
这是logcat:
03-16 16:38:25.478: W/System.err(21199): java.net.ProtocolException: Unexpected status line: <html>
03-16 16:38:25.480: W/System.err(21199): at com.android.okhttp.internal.http.RawHeaders.setStatusLine(RawHeaders.java:108)
03-16 16:38:25.480: W/System.err(21199): at com.android.okhttp.internal.http.RawHeaders.fromBytes(RawHeaders.java:308)
03-16 16:38:25.481: W/System.err(21199): at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:135)
03-16 16:38:25.482: W/System.err(21199): at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:644)
03-16 16:38:25.483: W/System.err(21199): at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:347)
03-16 16:38:25.483: W/System.err(21199): at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
03-16 16:38:25.484: W/System.err(21199): at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
03-16 16:38:25.484: W/System.err(21199): at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
03-16 16:38:25.486: W/System.err(21199): at com.eatl.bdtoolkits.parsers.xmlparser.downloader.ResourceDownloader.saveResourcesToSDCard(ResourceDownloader.java:68)
03-16 16:38:25.486: W/System.err(21199): at com.eatl.bdtoolkits.parsers.xmlparser.downloader.ResourceDownloader$DownloadResourceTask.doInBackground(ResourceDownloader.java:127)
03-16 16:38:25.487: W/System.err(21199): at com.eatl.bdtoolkits.parsers.xmlparser.downloader.ResourceDownloader$DownloadResourceTask.doInBackground(ResourceDownloader.java:1)
03-16 16:38:25.487: W/System.err(21199): at android.os.AsyncTask$2.call(AsyncTask.java:288)
03-16 16:38:25.488: W/System.err(21199): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-16 16:38:25.489: W/System.err(21199): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
03-16 16:38:25.490: W/System.err(21199): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-16 16:38:25.491: W/System.err(21199): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-16 16:38:25.491: W/System.err(21199): at java.lang.Thread.run(Thread.java:841)
我错过了什么?
答案 0 :(得分:1)
https://www.k4health.org/sites/default/files/প্রসব জনতি ফিস্টুলা চিহ্নিত করার চেকলিস্ট H11.pdf
这不是一个URI。它几乎是IRI,它可以包含非ASCII字符,但不完全是因为它的空格对URI和IRI都无效。
您需要对文件名进行URL编码(使用IRI指定的非ASCII字符的UTF-8编码)
String encoded_name = URLEncoder.encode("প্রসব জনতি ফিস্টুলা চিহ্নিত করার চেকলিস্ট H11.pdf", "utf-8")
.replaceAll("\\+", "%20")
String url = "https://www.k4health.org/sites/default/files/" + encoded_name;
以有效的URI结尾:
https://www.k4health.org/sites/default/files/%E0%A6%AA%E0%A7%8D%E0%A6%B0%E0%A6%B8%E0%A6%AC%20%E0%A6%9C%E0%A6%A8%E0%A6%A4%E0%A6%BF%20%E0%A6%AB%E0%A6%BF%E0%A6%B8%E0%A7%8D%E0%A6%9F%E0%A7%81%E0%A6%B2%E0%A6%BE%20%E0%A6%9A%E0%A6%BF%E0%A6%B9%E0%A7%8D%E0%A6%A8%E0%A6%BF%E0%A6%A4%20%E0%A6%95%E0%A6%B0%E0%A6%BE%E0%A6%B0%20%E0%A6%9A%E0%A7%87%E0%A6%95%E0%A6%B2%E0%A6%BF%E0%A6%B8%E0%A7%8D%E0%A6%9F%20H11.pdf
(请注意,用+
替换%20
是必要的,因为Java URLEncoder
实际上是URL查询字符串中HTML表单的编码器,其中+
对于空格是首选。这不适用于需要明确%20
的路径。)
答案 1 :(得分:-1)
我通过这样做得到了解决方案:
public String saveResourcesToSDCard(Resource res) {
String filepath = null;
String respath = "/bccp/" + bookID + "/resources/";
StringBuilder sb = new StringBuilder();
try {
sb.append(Constant.RESOURCE_FTP);
String resfile = URLEncoder.encode(res.filename, "utf-8");
String newfile = StringUtils.replace(resfile, "+", "%20");
sb.append(newfile);
Log.i("URL:", " " + sb.toString());
URL url = new URL(sb.toString());
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
if(createDirIfNotExists(respath)){
String filename = res.filename;
Log.i("Local filename:", " " + filename);
Log.i("URL:", " " + sb.toString());
File file = new File(SDCardRoot, filename);
if (file.createNewFile()) {
file.createNewFile();
}
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
int totalSize = urlConnection.getContentLength();
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
Log.v("Progress:", "DownloadedSize: " + downloadedSize
+ " TotalSize: " + totalSize);
}
fileOutput.close();
if (downloadedSize == totalSize){
filepath = file.getPath();
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
//restartTask();
} catch (IOException e) {
filepath = null;
//restartTask();
e.printStackTrace();
}
Log.v("filepath:", " " + filepath);
return filepath;
}