目前用java在做一个「多线程下载工具」,想要实现类似迅雷那样自动识别url所指资源的文件名和后缀。尝试以下办法:
HttpURLConnection http = (HttpURLConnection)url.openConnection();
http.connect();String field=http.getHeaderField("Content-Disposition");
String tmpStr1=field.substring(field.indexOf("filename")+10, field.length()-1); //获取filename="xxx"中的xxx
String tmpStr2=new String(tmpStr1.getBytes("ISO-8859-1"), "GB2312"); //编码转换,正确识别中文
System.out.println(tmpStr2);
遇到两个问题:
1、String tmpStr2=new String(tmpStr1.getBytes("ISO-8859-1"), "GB2312");
对某些http响应信息里的中文字符,依然会出现乱码。http的默认编码不是“ISO-8859-1”吗?还是说有别的问题?2、这段代码只能获取某些url的文件名和后缀,对很多url无效。我检查了一下这些url的http响应信息,不含Content-Disposition字段。这是为什么?请高手不吝赐教,有没有一种强健的方式能够获取url所指资源的真实文件名和后缀。非常感谢。
HttpURLConnection http = (HttpURLConnection)url.openConnection();
http.connect();String field=http.getHeaderField("Content-Disposition");
String tmpStr1=field.substring(field.indexOf("filename")+10, field.length()-1); //获取filename="xxx"中的xxx
String tmpStr2=new String(tmpStr1.getBytes("ISO-8859-1"), "GB2312"); //编码转换,正确识别中文
System.out.println(tmpStr2);
遇到两个问题:
1、String tmpStr2=new String(tmpStr1.getBytes("ISO-8859-1"), "GB2312");
对某些http响应信息里的中文字符,依然会出现乱码。http的默认编码不是“ISO-8859-1”吗?还是说有别的问题?2、这段代码只能获取某些url的文件名和后缀,对很多url无效。我检查了一下这些url的http响应信息,不含Content-Disposition字段。这是为什么?请高手不吝赐教,有没有一种强健的方式能够获取url所指资源的真实文件名和后缀。非常感谢。
{
long startPos=0,endPos=0;
String currentFileThreadName;//要带上完整的路径
String urlFile;//网络文件地址
String urlFileName;//网络文件名
String localFileAddress;//下载文件要存放的地址
int threadNum;//要同时下载的线程数
long[] eachThreadLength;//每个线程要下功的文件分块的大小
long urlFileLength;//网络文件的大小
URL url;
HttpURLConnection httpURLConnection;
public static boolean[] checkList;//检测线程
public MultiThreadGetFile(String urlFile,int threadNum,String localFileAddress)
{
this.urlFile=urlFile;
this.threadNum=threadNum;//要同时下载的线程数
this.localFileAddress=localFileAddress;
}
private void init_getEachThreadLength()//确定每个线程文件最终要写的文件在大小
{
long l;
l=urlFileLength/threadNum;
for(int i=0;i<threadNum;i++)
{
if(i==threadNum-1)//如果是分配最后一个线程了
{
eachThreadLength[i]=urlFileLength-i*l;
}
else
eachThreadLength[i]=l;
}
}
private String GetFileName(String file)
{
StringTokenizer st=new StringTokenizer(file,"/");
while(st.hasMoreTokens())
{
file=st.nextToken();
}
return file;
}
private void init()
{
if(!new File(localFileAddress+"tmp").mkdir())//创建一个临时文件夹
{
System.out.println("创建文件夹失败!");
}
eachThreadLength=new long[threadNum];
try
{
url=new URL(urlFile);
httpURLConnection=(HttpURLConnection)url.openConnection();
urlFileLength=Long.parseLong(httpURLConnection.getHeaderField("Content-Length"));
urlFileName=url.getFile();//取得在服务器上的路径及文件名
urlFileName=GetFileName(urlFileName);//只得文件名
init_getEachThreadLength();
httpURLConnection.disconnect();
checkList=new boolean[threadNum+1];
for(int i=1;i<=threadNum;i++)
{
if(i>1)
startPos=startPos+eachThreadLength[i-2];
endPos=startPos+eachThreadLength[i-1];
currentFileThreadName=localFileAddress+"tmp\\"+urlFileName+".part"+i;
//System.out.println("startPos:"+(startPos));
//System.out.println("endPos:"+(endPos));
//System.out.println("Size:"+(endPos-startPos));
Thread thread=new Thread(new GetFileThread(urlFile,startPos,endPos,currentFileThreadName,i));
thread.start();
checkList[i]=false;//表示该线程开始
}
Thread policeThread=new Thread(new PoliceThread(threadNum,localFileAddress,localFileAddress+"tmp"));
policeThread.start();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void run()
{
init();
}
}
2、Content-Disposition一般是下载时,服务器用来设置文件名用,如果服务器下载时没提供这个报头,一般有个默认的文件名,好像是download,这样就比较难解析出真实文件名了,因为报头没有其他可用信息