|
|
|
@ -24,8 +24,13 @@ import com.arialyy.aria.core.download.DownloadTaskEntity; |
|
|
|
|
import com.arialyy.aria.core.inf.IDownloadListener; |
|
|
|
|
import com.arialyy.aria.util.ALog; |
|
|
|
|
import com.arialyy.aria.util.BufferedRandomAccessFile; |
|
|
|
|
import java.io.FileOutputStream; |
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.io.InputStream; |
|
|
|
|
import java.nio.ByteBuffer; |
|
|
|
|
import java.nio.channels.Channels; |
|
|
|
|
import java.nio.channels.FileChannel; |
|
|
|
|
import java.nio.channels.ReadableByteChannel; |
|
|
|
|
import org.apache.commons.net.ftp.FTPClient; |
|
|
|
|
import org.apache.commons.net.ftp.FTPReply; |
|
|
|
|
|
|
|
|
@ -36,10 +41,6 @@ import org.apache.commons.net.ftp.FTPReply; |
|
|
|
|
class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> { |
|
|
|
|
private final String TAG = "FtpThreadTask"; |
|
|
|
|
private boolean isOpenDynamicFile; |
|
|
|
|
/** |
|
|
|
|
* 2M的动态长度 |
|
|
|
|
*/ |
|
|
|
|
private final int LEN_INTERVAL = 1024 * 1024 * 2; |
|
|
|
|
|
|
|
|
|
FtpThreadTask(StateConstance constance, IDownloadListener listener, |
|
|
|
|
SubThreadConfig<DownloadTaskEntity> downloadInfo) { |
|
|
|
@ -49,7 +50,7 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> |
|
|
|
|
mReadTimeOut = manager.getDownloadConfig().getIOTimeOut(); |
|
|
|
|
mBufSize = manager.getDownloadConfig().getBuffSize(); |
|
|
|
|
isNotNetRetry = manager.getDownloadConfig().isNotNetRetry(); |
|
|
|
|
isOpenDynamicFile = STATE.TASK_RECORD.isOpenDynamicFile; |
|
|
|
|
isOpenDynamicFile = STATE.isOpenDynamicFile; |
|
|
|
|
setMaxSpeed(manager.getDownloadConfig().getMaxSpeed()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -58,7 +59,7 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> |
|
|
|
|
mChildCurrentLocation = mConfig.START_LOCATION; |
|
|
|
|
FTPClient client = null; |
|
|
|
|
InputStream is = null; |
|
|
|
|
BufferedRandomAccessFile file = null; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
ALog.d(TAG, "任务【" |
|
|
|
|
+ mConfig.TEMP_FILE.getName() |
|
|
|
@ -94,31 +95,12 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize); |
|
|
|
|
file.seek(mConfig.START_LOCATION); |
|
|
|
|
byte[] buffer = new byte[mBufSize]; |
|
|
|
|
int len; |
|
|
|
|
|
|
|
|
|
while ((len = is.read(buffer)) != -1) { |
|
|
|
|
if (STATE.isCancel || STATE.isStop) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (mSleepTime > 0) Thread.sleep(mSleepTime); |
|
|
|
|
if (isOpenDynamicFile) { |
|
|
|
|
file.setLength( |
|
|
|
|
STATE.CURRENT_LOCATION + LEN_INTERVAL < mEntity.getFileSize() ? STATE.CURRENT_LOCATION |
|
|
|
|
+ LEN_INTERVAL : mEntity.getFileSize()); |
|
|
|
|
} |
|
|
|
|
if (mChildCurrentLocation + len >= mConfig.END_LOCATION) { |
|
|
|
|
len = (int) (mConfig.END_LOCATION - mChildCurrentLocation); |
|
|
|
|
file.write(buffer, 0, len); |
|
|
|
|
progress(len); |
|
|
|
|
break; |
|
|
|
|
} else { |
|
|
|
|
file.write(buffer, 0, len); |
|
|
|
|
progress(len); |
|
|
|
|
} |
|
|
|
|
if (isOpenDynamicFile) { |
|
|
|
|
readDynamicFile(is); |
|
|
|
|
} else { |
|
|
|
|
readNormal(is); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (STATE.isCancel || STATE.isStop) return; |
|
|
|
|
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__下载完毕"); |
|
|
|
|
writeConfig(true, 1); |
|
|
|
@ -138,9 +120,6 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> |
|
|
|
|
fail(mChildCurrentLocation, "获取流失败", e); |
|
|
|
|
} finally { |
|
|
|
|
try { |
|
|
|
|
if (file != null) { |
|
|
|
|
file.close(); |
|
|
|
|
} |
|
|
|
|
if (is != null) { |
|
|
|
|
is.close(); |
|
|
|
|
} |
|
|
|
@ -153,6 +132,92 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 动态长度文件读取方式 |
|
|
|
|
*/ |
|
|
|
|
private void readDynamicFile(InputStream is) { |
|
|
|
|
FileOutputStream fos = null; |
|
|
|
|
FileChannel foc = null; |
|
|
|
|
ReadableByteChannel fic = null; |
|
|
|
|
try { |
|
|
|
|
int len; |
|
|
|
|
fos = new FileOutputStream(mConfig.TEMP_FILE, true); |
|
|
|
|
foc = fos.getChannel(); |
|
|
|
|
fic = Channels.newChannel(is); |
|
|
|
|
ByteBuffer bf = ByteBuffer.allocate(mBufSize); |
|
|
|
|
while ((len = fic.read(bf)) != -1) { |
|
|
|
|
if (STATE.isCancel || STATE.isStop) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (mSleepTime > 0) { |
|
|
|
|
Thread.sleep(mSleepTime); |
|
|
|
|
} |
|
|
|
|
bf.flip(); |
|
|
|
|
foc.write(bf); |
|
|
|
|
bf.compact(); |
|
|
|
|
progress(len); |
|
|
|
|
} |
|
|
|
|
} catch (InterruptedException e) { |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} catch (IOException e) { |
|
|
|
|
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e); |
|
|
|
|
} finally { |
|
|
|
|
try { |
|
|
|
|
if (fos != null) { |
|
|
|
|
fos.close(); |
|
|
|
|
} |
|
|
|
|
if (foc != null) { |
|
|
|
|
foc.close(); |
|
|
|
|
} |
|
|
|
|
if (fic != null) { |
|
|
|
|
fic.close(); |
|
|
|
|
} |
|
|
|
|
} catch (IOException e) { |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 多线程写文件方式 |
|
|
|
|
*/ |
|
|
|
|
private void readNormal(InputStream is) { |
|
|
|
|
BufferedRandomAccessFile file = null; |
|
|
|
|
try { |
|
|
|
|
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize); |
|
|
|
|
file.seek(mConfig.START_LOCATION); |
|
|
|
|
byte[] buffer = new byte[mBufSize]; |
|
|
|
|
int len; |
|
|
|
|
while ((len = is.read(buffer)) != -1) { |
|
|
|
|
if (STATE.isCancel || STATE.isStop) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (mSleepTime > 0) Thread.sleep(mSleepTime); |
|
|
|
|
if (mChildCurrentLocation + len >= mConfig.END_LOCATION) { |
|
|
|
|
len = (int) (mConfig.END_LOCATION - mChildCurrentLocation); |
|
|
|
|
file.write(buffer, 0, len); |
|
|
|
|
progress(len); |
|
|
|
|
break; |
|
|
|
|
} else { |
|
|
|
|
file.write(buffer, 0, len); |
|
|
|
|
progress(len); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} catch (IOException e) { |
|
|
|
|
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e); |
|
|
|
|
} catch (InterruptedException e) { |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} finally { |
|
|
|
|
try { |
|
|
|
|
if (file != null) { |
|
|
|
|
file.close(); |
|
|
|
|
} |
|
|
|
|
} catch (IOException e) { |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override protected String getTaskType() { |
|
|
|
|
return "FTP_DOWNLOAD"; |
|
|
|
|
} |
|
|
|
|