前段时间我使用用java写一个多线程下载工具,使用URL对象时发现在子线程中URL对象创建后,程序直接退出,我改到主线程中就没有任何问题。
package filedownload;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.logging.*;
public class FileDownLoad implements Runnable {
private String fileURL;
private Logger logger;
public FileDownLoad(String url){
fileURL = url;
logger = Logger.getLogger("filedownload");
logger.setLevel(Level.INFO);
}
@Override
public void run() {
String fileBasename = fileURL.substring(fileURL.lastIndexOf("/")+1);
try{
logger.info("DownLoad form"+ fileURL);
URL url = new URL("http://github.com/orhanobut/logger/archive/master.zip");
String loacalURL = "/home/sosky/"+fileBasename;
logger.info("saving in "+ loacalURL);
DownLoadFromURL(url, new FileOutputStream(loacalURL),1024);
} catch(Exception e){
e.printStackTrace();
logger.info(e.toString());
}
}
//测试函数
public void test(URL url, String loacal){
try {
DownLoadFromURL(url, new FileOutputStream(loacal),1024);
} catch (IOException e) {
e.printStackTrace();
}
}
private void DownLoadFromURL(URL url, FileOutputStream outputStream , int bufSize)
throws MalformedURLException,IOException{
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
ReadableByteChannel read = null;
WritableByteChannel write = null;
try{
int respon = connection.getResponseCode();
if (2!=(respon/100)){
throw new IOException("Http exception :"+respon);
}
if (0==connection.getContentLength()){
// throw new IOException("nothing to download!!!");
logger.info("nothing to download!!!");
return;
}
read = Channels.newChannel(new BufferedInputStream(connection.getInputStream()));
write = Channels.newChannel(new BufferedOutputStream(outputStream));
ByteBuffer byteBuffer = ByteBuffer.allocate(bufSize);
while(-1!=read.read(byteBuffer)){
byteBuffer.flip();
write.write(byteBuffer);
byteBuffer.clear();
}
}finally{
silentClose(read,write);
}
}
public static void silentClose(Closeable... closeable) {
if (null == closeable) {
return;
}
for (Closeable c : closeable) {
if (null == c) {
continue;
}
try {
c.close();
} catch (Exception ignored) {
}
}
}
}
测试类如下:
public class filedownloadtest {
/**
* URL对象在子线程创建过程中会导致程序退出,切且返回码为0,没有抛出任何异常,待解决
*/
@ToBeSolved(date="sosky",methodName = "download",className = "filedownloadtest",
desicripition = "URL对象在子线程创建过程中会导致程序退出,切且返回码为0,没有抛出任何异常")
@Test
public void download(){
String url = "http://github.com/orhanobut/logger/archive/master.zip";
Thread downThread = new Thread(new FileDownLoad(url));
//downThread.start();
}
/**
* URL对象创建主线程中创建成功
*/
@Test
public void mainthread(){
try {
FileDownLoad downLoad = new FileDownLoad("123");
URL url = new URL("https://github.com/square/leakcanary/archive/master.zip");
downLoad.test(url,"/home/sosky/master.zip");
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
结语
URL对象应创建主线程中,在子线程中创建会导致程序貌似正常退出,但是后面的代码都不执行,具体原因我还不清楚,有大佬知道望告知。