下载的文件不带扩展名从服务器 [英] Download a file with no extension from a server
问题描述
我尝试从以下网址下载一个MP3文件。我发现很多有关文件下载文章和例子。这些例子都基于同一个文件扩展名,如结尾的URL: - yourdomain.com/filename.mp3
,但我想从以下网址通常不下载文件结尾的文件扩展名。
<$c$c>youtubeinmp3.com/download/get/?i=1gsE32jF0aVaY0smDVf%2BmwnIZPrMDnGmchHBu0Hovd3Hl4NYqjNdym4RqjDSAis7p1n5O%2BeXmdwFxK9ugErLWQ%3D%3D$c$c>
**请注意,我用的是上面的网址,是不使用#1的URL格式的方法很容易理解这个问题。
** 我已经试过了@Arsal阿訇的解决方案如下仍无法正常工作
btnShowProgress.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
//开始新的异步任务
文件cacheDir =新的文件(android.os.Environment.getExternalStorageDirectory(),文件夹名称);
如果(!cacheDir.exists())
cacheDir.mkdirs();
文件F =新的文件(cacheDir,ddedddddd.mp3);
SaveDir可以= f.getPath();
新DownloadFileFromURL()执行(fileURL);
}
});
和异步任务code如下:
类DownloadFileFromURL扩展的AsyncTask&LT;字符串,字符串,字符串&GT; {
@覆盖
在preExecute保护无效(){
super.on preExecute();
的ShowDialog(progress_bar_type);
}
@覆盖
保护字符串doInBackground(字符串... f_url){
尝试{
网址URL =新的URL(fileURL);
HttpURLConnection的httpConn =(HttpURLConnection类)url.openConnection();
INT响应code = httpConn.getResponse code();
//总是先检查HTTP响应code
如果(响应code == HttpURLConnection.HTTP_OK){
字符串文件名=;
字符串处置= httpConn.getHeaderField(内容处置);
字符串的contentType = httpConn.getContentType();
INT CONTENTLENGTH = httpConn.getContentLength();
如果(处置!= NULL){
//摘录头字段文件名
INT指数= disposition.indexOf(文件名=);
如果(指数大于0){
文件名= disposition.substring(指数+ 10,
disposition.length() - 1);
}
} 其他 {
//摘录URL文件名
文件名= fileURL.substring(fileURL.lastIndexOf(/)+ 1,
fileURL.length());
}
的System.out.println(内容类型=+的contentType);
的System.out.println(内容处置=+配置);
的System.out.println(内容长度=+ CONTENTLENGTH);
的System.out.println(文件名=+文件名);
//从HTTP连接打开输入流
InputStream中的InputStream = httpConn.getInputStream();
字符串SAVEFILEPATH = SaveDir可以+文件分割符+文件名;
//打开输出流保存到文件
FileOutputStream中的OutputStream =新的FileOutputStream(SaveDir可以);
INT读取动作= -1;
byte []的缓冲区=新的字节[BUFFER_SIZE];
而((读取动作= inputStream.read(缓冲液))!= - 1){
outputStream.write(缓冲液,0,读取动作);
}
outputStream.close();
inputStream.close();
的System.out.println(文件下载);
} 其他 {
的System.out.println(没有文件下载服务器回答HTTP code:+响应code);
}
httpConn.disconnect();
}赶上(例外五){
e.printStackTrace();
}
返回null;
}
保护无效onProgressUpdate(字符串...进度){
pDialog.setProgress(的Integer.parseInt(进展[0]));
}
@覆盖
保护无效onPostExecute(字符串file_url){
dismissDialog(progress_bar_type);
}
}
虽然 凌空库是不建议大量下载或流操作,但是,我想与大家分享我的以下工作示例code。
假设我们只下载 MP3 文件,所以我硬code扩展。当然,我们应该检查更仔细,以避免异常(空指针......)如检查头中是否带有内容处置
键或不...
希望这有助于!
凌空自定义类:
公共类BaseVolleyRequest扩展请求&LT; NetworkResponse&GT; {
私人最终Response.Listener&LT; NetworkResponse&GT; mListener;
私人最终Response.ErrorListener mErrorListener;
公共BaseVolleyRequest(字符串URL,Response.Listener&LT; NetworkResponse&GT;听者,Response.ErrorListener errorListener){
超(0,网址,errorListener);
this.mListener =侦听器;
this.mErrorListener = errorListener;
}
@覆盖
受保护的响应和LT; NetworkResponse&GT; parseNetworkResponse(NetworkResponse响应){
尝试 {
返回Response.success(
响应,
HttpHeaderParser.parseCacheHeaders(响应));
}赶上(JsonSyntaxException E){
返回Response.error(新ParseError(e)条);
}赶上(例外五){
返回Response.error(新ParseError(e)条);
}
}
@覆盖
保护无效deliverResponse(NetworkResponse响应){
mListener.onResponse(响应);
}
@覆盖
保护VolleyError parseNetworkError(VolleyError volleyError){
返回super.parseNetworkError(volleyError);
}
@覆盖
公共无效deliverError(VolleyError错误){
mErrorListener.onErrorResponse(错误);
}
}
然后在您的活动:
公共类BinaryVolleyActivity扩展AppCompatActivity {
私人最终上下文mContext =这一点;
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_binary_volley);
请求队列请求队列= Volley.newRequestQueue(mContext);
字符串URL = "http://www.youtubeinmp3.com/download/get/?i=3sI2yV5mJ0kQ8CnddqmANZqK8a%2BgVQJ%2Fmg3xwhHTUsJKuusOCZUzebuWW%2BJSFs0oz8VTs6ES3gjohKQMogixlQ%3D%3D";
BaseVolleyRequest volleyRequest =新BaseVolleyRequest(URL,新Response.Listener&LT; NetworkResponse&GT;(){
@覆盖
公共无效onResponse(NetworkResponse响应){
地图&LT;字符串,字符串&GT;标题= response.headers;
字符串contentDisposition = headers.get(内容处置);
//字符串的contentType = headers.get(内容类型);
的String []临时= contentDisposition.split(文件名=);
字符串文件名=温度[1] .replace(\,)+.MP3;
的InputStream的InputStream =新ByteArrayInputStream的(response.data);
createLocalFile(InputStream中,文件名);
}
},新Response.ErrorListener(){
@覆盖
公共无效onErrorResponse(VolleyError错误){
Log.e(排球,error.toString());
}
});
volleyRequest.setRetryPolicy(新DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 10,DefaultRetryPolicy.DEFAULT_MAX_RETRIES,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(volleyRequest);
}
私人字符串createLocalFile(InputStream中的InputStream,字符串文件名){
尝试 {
字符串夹folderName =MP3VOLLEY;
。字符串extStorageDirectory = Environment.getExternalStorageDirectory()的toString();
文件夹=新的文件(extStorageDirectory,夹folderName);
folder.mkdir();
档案文件=新的文件(文件夹中,文件名);
file.createNewFile();
FileOutputStream中F =新的FileOutputStream(文件);
byte []的缓冲区=新的字节[1024];
INT长;
而((长度= inputStream.read(缓冲液))大于0){
f.write(缓冲液,0,长度);
}
//f.flush();
f.close();
返回file.getPath();
}赶上(IOException异常E){
返回e.getMessage();
}
}
}
下面的结果截图:
注意:
正如我在下面评论,因为直接下载网址定期更换,您应该检查新的URL的一些工具,如邮差针对Chrome浏览器,如果它的响应二进制,而不是一个网页(网址已过期),则该地址是有效的,我的code适用于该URL。
请参照以下两个截图:
过期网址:
未到期网址:
获取直接下载链接从该网站的文档的更新基本逻辑:
您可以看看
JSON示例
您还可以通过设置格式接收JSON数据 参数设置为JSON。 <一href="http://YouTubeInMP3.com/fetch/?format=JSON&video=http://www.youtube.com/watch?v=i62Zjga8JOM" rel="nofollow">http://YouTubeInMP3.com/fetch/?format=JSON&video=http://www.youtube.com/watch?v=i62Zjga8JOM
首先,创建一个 JsonObjectRequest
获取从上面的文件链接响应。然后,在 onResponse
这个 JsonObjectRequest
您将得到直接的下载链接,像这样 directUrl = response.getString(链接);
和使用 BaseVolleyRequest volleyRequest
我刚才说的逻辑越来越直接链接,海事组织,你应该自己实现它。好运!
I'm try to download a mp3 file from following URL. I found lot of articles and examples regarding file download. Those examples are based on URLs that end with a file extension, e.g.:- yourdomain.com/filename.mp3
but I want to download a file from following url which typically does not end with file extension.
youtubeinmp3.com/download/get/?i=1gsE32jF0aVaY0smDVf%2BmwnIZPrMDnGmchHBu0Hovd3Hl4NYqjNdym4RqjDSAis7p1n5O%2BeXmdwFxK9ugErLWQ%3D%3D
**Please note that I use the above url as-is without using Stackoverflow url formatting method to easily understand the question.
** I have tried the @Arsal Imam's solution as follows still not working
btnShowProgress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// starting new Async Task
File cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"Folder Name");
if(!cacheDir.exists())
cacheDir.mkdirs();
File f=new File(cacheDir,"ddedddddd.mp3");
saveDir=f.getPath();
new DownloadFileFromURL().execute(fileURL);
}
});
and the async task code is as follows
class DownloadFileFromURL extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
@Override
protected String doInBackground(String... f_url) {
try{
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveDir);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}catch(Exception e){
e.printStackTrace();
}
return null;
}
protected void onProgressUpdate(String... progress) {
pDialog.setProgress(Integer.parseInt(progress[0]));
}
@Override
protected void onPostExecute(String file_url) {
dismissDialog(progress_bar_type);
}
}
Although Volley library is not recommended for large download or streaming operations, however, I'd like to share my following working sample code.
Let's assume we download only MP3 files so I hard-code the extension. And of course, we should check more carefully to avoid exceptions (NullPointer...) such as checking whether headers contain "Content-Disposition"
key or not...
Hope this helps!
Volley Custom class:
public class BaseVolleyRequest extends Request<NetworkResponse> {
private final Response.Listener<NetworkResponse> mListener;
private final Response.ErrorListener mErrorListener;
public BaseVolleyRequest(String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(0, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
@Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
try {
return Response.success(
response,
HttpHeaderParser.parseCacheHeaders(response));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
@Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return super.parseNetworkError(volleyError);
}
@Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
}
Then in your Activity:
public class BinaryVolleyActivity extends AppCompatActivity {
private final Context mContext = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_binary_volley);
RequestQueue requestQueue = Volley.newRequestQueue(mContext);
String url = "http://www.youtubeinmp3.com/download/get/?i=3sI2yV5mJ0kQ8CnddqmANZqK8a%2BgVQJ%2Fmg3xwhHTUsJKuusOCZUzebuWW%2BJSFs0oz8VTs6ES3gjohKQMogixlQ%3D%3D";
BaseVolleyRequest volleyRequest = new BaseVolleyRequest(url, new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
Map<String, String> headers = response.headers;
String contentDisposition = headers.get("Content-Disposition");
// String contentType = headers.get("Content-Type");
String[] temp = contentDisposition.split("filename=");
String fileName = temp[1].replace("\"", "") + ".mp3";
InputStream inputStream = new ByteArrayInputStream(response.data);
createLocalFile(inputStream, fileName);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
}
});
volleyRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 10, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(volleyRequest);
}
private String createLocalFile(InputStream inputStream, String fileName) {
try {
String folderName = "MP3VOLLEY";
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, folderName);
folder.mkdir();
File file = new File(folder, fileName);
file.createNewFile();
FileOutputStream f = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
f.write(buffer, 0, length);
}
//f.flush();
f.close();
return file.getPath();
} catch (IOException e) {
return e.getMessage();
}
}
}
Here the result screenshot:
NOTE:
As I commented below, because the direct download Url changes regularly, you should check the new url with some tools such as Postman for Chrome, if it responses binary instead of a web page (expired url), then the Url is valid and my code works for that Url.
Refer to the two following screenshots:
Expired url:
Un-expired url:
UPDATE BASIC LOGIC FOR GETTING DIRECT DOWNLOAD LINK FROM THAT SITE'S DOCUMENTATION:
According to Create Your Own YouTube To MP3 Downloader For Free
You can take a look at
JSON Example
You can also receive the data in JSON by setting the "format" parameter to "JSON". http://YouTubeInMP3.com/fetch/?format=JSON&video=http://www.youtube.com/watch?v=i62Zjga8JOM
Firstly, you create a JsonObjectRequest
getting response from the above file link. Then, inside onResponse
of this JsonObjectRequest
you will get the direct download link, like this directUrl = response.getString("link");
and use BaseVolleyRequest volleyRequest
I have just told the logic for getting direct url, IMO, you should implement it yourself. Goodluck!
这篇关于下载的文件不带扩展名从服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!