diff --git a/okdownload/src/main/java/com/liulishuo/okdownload/DownloadTask.java b/okdownload/src/main/java/com/liulishuo/okdownload/DownloadTask.java index 5a6eded6..b61defd4 100644 --- a/okdownload/src/main/java/com/liulishuo/okdownload/DownloadTask.java +++ b/okdownload/src/main/java/com/liulishuo/okdownload/DownloadTask.java @@ -66,7 +66,8 @@ public class DownloadTask extends IdentifiedTask implements Cloneable, Comparabl private final int syncBufferSize; private final int syncBufferIntervalMills; - private final Integer connectionCount; + @Nullable private final Integer connectionCount; + @Nullable private final Boolean isPreAllocateLength; /** * if this task has already completed with @@ -96,7 +97,8 @@ public DownloadTask(String url, Uri uri, int priority, int readBufferSize, int f boolean autoCallbackToUIThread, int minIntervalMillisCallbackProcess, Map> headerMapFields, @Nullable String filename, boolean passIfAlreadyCompleted, boolean isWifiRequired, - Boolean isFilenameFromResponse, Integer connectionCount) { + Boolean isFilenameFromResponse, @Nullable Integer connectionCount, + @Nullable Boolean isPreAllocateLength) { this.url = url; this.uri = uri; this.priority = priority; @@ -111,6 +113,7 @@ public DownloadTask(String url, Uri uri, int priority, int readBufferSize, int f this.passIfAlreadyCompleted = passIfAlreadyCompleted; this.isWifiRequired = isWifiRequired; this.connectionCount = connectionCount; + this.isPreAllocateLength = isPreAllocateLength; if (Util.isUriFileScheme(uri)) { final File file = new File(uri.getPath()); @@ -364,10 +367,20 @@ public int getMinIntervalMillisCallbackProcess() { * * @return the connection count you set. */ - public Integer getSetConnectionCount() { + @Nullable public Integer getSetConnectionCount() { return connectionCount; } + /** + * Get whether need to pre-allocate length for the file to it's instant-length from trial + * connection you set through {@link Builder#setPreAllocateLength(boolean)}. + * + * @return whether need to pre-allocate length you set. + */ + @Nullable public Boolean getSetPreAllocateLength() { + return isPreAllocateLength; + } + /** * Get the connection count is effect on this task. * @@ -675,6 +688,19 @@ public Builder(@NonNull String url, @NonNull Uri uri) { private Boolean isFilenameFromResponse; private Integer connectionCount; + private Boolean isPreAllocateLength; + + /** + * Set whether need to pre allocate length for the file after get the resource-length from + * trial-connection. + * + * @param preAllocateLength whether need to pre allocate length for the file before + * download. + */ + public Builder setPreAllocateLength(boolean preAllocateLength) { + isPreAllocateLength = preAllocateLength; + return this; + } /** * Set the count of connection establish for this task, if this task has already split block @@ -872,7 +898,7 @@ public DownloadTask build() { syncBufferSize, syncBufferIntervalMillis, autoCallbackToUIThread, minIntervalMillisCallbackProcess, headerMapFields, filename, passIfAlreadyCompleted, isWifiRequired, - isFilenameFromResponse, connectionCount); + isFilenameFromResponse, connectionCount, isPreAllocateLength); } } diff --git a/okdownload/src/main/java/com/liulishuo/okdownload/core/download/BreakpointLocalCheck.java b/okdownload/src/main/java/com/liulishuo/okdownload/core/download/BreakpointLocalCheck.java index 30de97d0..32c2e71c 100644 --- a/okdownload/src/main/java/com/liulishuo/okdownload/core/download/BreakpointLocalCheck.java +++ b/okdownload/src/main/java/com/liulishuo/okdownload/core/download/BreakpointLocalCheck.java @@ -101,7 +101,7 @@ public boolean isOutputStreamSupportResume() { if (supportSeek) return true; if (info.getBlockCount() != 1) return false; - if (OkDownload.with().processFileStrategy().isPreAllocateLength()) return false; + if (OkDownload.with().processFileStrategy().isPreAllocateLength(task)) return false; return true; } diff --git a/okdownload/src/main/java/com/liulishuo/okdownload/core/file/MultiPointOutputStream.java b/okdownload/src/main/java/com/liulishuo/okdownload/core/file/MultiPointOutputStream.java index 8ced6212..e87fb931 100644 --- a/okdownload/src/main/java/com/liulishuo/okdownload/core/file/MultiPointOutputStream.java +++ b/okdownload/src/main/java/com/liulishuo/okdownload/core/file/MultiPointOutputStream.java @@ -89,7 +89,8 @@ public class MultiPointOutputStream { this.store = store; this.supportSeek = OkDownload.with().outputStreamFactory().supportSeek(); - this.isPreAllocateLength = OkDownload.with().processFileStrategy().isPreAllocateLength(); + this.isPreAllocateLength = OkDownload.with().processFileStrategy() + .isPreAllocateLength(task); this.noMoreStreamList = new ArrayList<>(); if (syncRunnable == null) { diff --git a/okdownload/src/main/java/com/liulishuo/okdownload/core/file/ProcessFileStrategy.java b/okdownload/src/main/java/com/liulishuo/okdownload/core/file/ProcessFileStrategy.java index 44ff0a3c..9560d989 100644 --- a/okdownload/src/main/java/com/liulishuo/okdownload/core/file/ProcessFileStrategy.java +++ b/okdownload/src/main/java/com/liulishuo/okdownload/core/file/ProcessFileStrategy.java @@ -56,8 +56,12 @@ public void discardProcess(@NonNull DownloadTask task) throws IOException { return fileLock; } - public boolean isPreAllocateLength() { + public boolean isPreAllocateLength(@NonNull DownloadTask task) { // if support seek, enable pre-allocate length. - return OkDownload.with().outputStreamFactory().supportSeek(); + boolean supportSeek = OkDownload.with().outputStreamFactory().supportSeek(); + if (!supportSeek) return false; + + if (task.getSetPreAllocateLength() != null) return task.getSetPreAllocateLength(); + return true; } } diff --git a/okdownload/src/test/java/com/liulishuo/okdownload/DownloadTaskTest.java b/okdownload/src/test/java/com/liulishuo/okdownload/DownloadTaskTest.java index e77c490a..333e4701 100644 --- a/okdownload/src/test/java/com/liulishuo/okdownload/DownloadTaskTest.java +++ b/okdownload/src/test/java/com/liulishuo/okdownload/DownloadTaskTest.java @@ -544,11 +544,20 @@ public void constructor_path() { .build(); // connection count. + assertThat(task.getSetConnectionCount()).isNull(); task = new DownloadTask .Builder("https://jacksgong.com", "not-exist", null) .setConnectionCount(2) .build(); assertThat(task.getSetConnectionCount()).isEqualTo(2); + + // pre-allocate-length + assertThat(task.getSetPreAllocateLength()).isNull(); + task = new DownloadTask + .Builder("https://jacksgong.com", "not-exist", null) + .setPreAllocateLength(true) + .build(); + assertThat(task.getSetPreAllocateLength()).isTrue(); } @Test diff --git a/okdownload/src/test/java/com/liulishuo/okdownload/core/download/BreakpointLocalCheckTest.java b/okdownload/src/test/java/com/liulishuo/okdownload/core/download/BreakpointLocalCheckTest.java index d0c05d66..b08b29ec 100644 --- a/okdownload/src/test/java/com/liulishuo/okdownload/core/download/BreakpointLocalCheckTest.java +++ b/okdownload/src/test/java/com/liulishuo/okdownload/core/download/BreakpointLocalCheckTest.java @@ -178,7 +178,7 @@ public void isOutputStreamSupportResume_support() throws IOException { when(info.getBlockCount()).thenReturn(1); // not pre allocate length final ProcessFileStrategy strategy = OkDownload.with().processFileStrategy(); - when(strategy.isPreAllocateLength()).thenReturn(false); + when(strategy.isPreAllocateLength(task)).thenReturn(false); assertThat(check.isOutputStreamSupportResume()).isTrue(); } @@ -195,7 +195,7 @@ public void isOutputStreamSupportResume_notSupport() throws IOException { when(info.getBlockCount()).thenReturn(1); // pre allocate length but not support seek final ProcessFileStrategy strategy = OkDownload.with().processFileStrategy(); - doReturn(true).when(strategy).isPreAllocateLength(); + doReturn(true).when(strategy).isPreAllocateLength(task); assertThat(check.isOutputStreamSupportResume()).isFalse(); } diff --git a/okdownload/src/test/java/com/liulishuo/okdownload/core/file/MultiPointOutputStreamTest.java b/okdownload/src/test/java/com/liulishuo/okdownload/core/file/MultiPointOutputStreamTest.java index 2f7ac4b1..32a59d6a 100644 --- a/okdownload/src/test/java/com/liulishuo/okdownload/core/file/MultiPointOutputStreamTest.java +++ b/okdownload/src/test/java/com/liulishuo/okdownload/core/file/MultiPointOutputStreamTest.java @@ -487,7 +487,7 @@ public void outputStream_nonFileScheme() throws IOException { private void prepareOutputStreamEnv() throws FileNotFoundException, PreAllocateException { when(OkDownload.with().outputStreamFactory().supportSeek()).thenReturn(true); - when(OkDownload.with().processFileStrategy().isPreAllocateLength()).thenReturn(true); + when(OkDownload.with().processFileStrategy().isPreAllocateLength(task)).thenReturn(true); when(OkDownload.with().outputStreamFactory().create(any(Context.class), any(Uri.class), anyInt())).thenReturn(mock(DownloadOutputStream.class)); // recreate for new values of support-seek and pre-allocate-length. diff --git a/okdownload/src/test/java/com/liulishuo/okdownload/core/file/ProcessFileStrategyTest.java b/okdownload/src/test/java/com/liulishuo/okdownload/core/file/ProcessFileStrategyTest.java index 51869c2c..f56f9e61 100644 --- a/okdownload/src/test/java/com/liulishuo/okdownload/core/file/ProcessFileStrategyTest.java +++ b/okdownload/src/test/java/com/liulishuo/okdownload/core/file/ProcessFileStrategyTest.java @@ -17,8 +17,8 @@ package com.liulishuo.okdownload.core.file; import com.liulishuo.okdownload.DownloadTask; +import com.liulishuo.okdownload.OkDownload; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -26,6 +26,8 @@ import java.io.File; import java.io.IOException; +import static com.liulishuo.okdownload.TestUtils.mockOkDownload; +import static org.assertj.core.api.Java6Assertions.assertThat; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -33,26 +35,49 @@ public class ProcessFileStrategyTest { private ProcessFileStrategy strategy; @Mock private DownloadTask task; - private final File existFile = new File("./exist-path"); @Before public void setup() throws IOException { initMocks(this); strategy = new ProcessFileStrategy(); + } + @Test + public void discardProcess() throws IOException { + final File existFile = new File("./exist-path"); existFile.createNewFile(); - } - @After - public void tearDown() { - existFile.delete(); + when(task.getFile()).thenReturn(existFile); + + strategy.discardProcess(task); + + assertThat(existFile.exists()).isFalse(); } @Test - public void discardProcess() throws IOException { - when(task.getFile()).thenReturn(new File("mock path")); + public void isPreAllocateLength() throws IOException { + mockOkDownload(); - strategy.discardProcess(task); - // nothing need to test. + // no pre-allocate set on task. + when(task.getSetPreAllocateLength()).thenReturn(null); + + final DownloadOutputStream.Factory factory = OkDownload.with().outputStreamFactory(); + when(factory.supportSeek()).thenReturn(false); + + assertThat(strategy.isPreAllocateLength(task)).isFalse(); + when(factory.supportSeek()).thenReturn(true); + + assertThat(strategy.isPreAllocateLength(task)).isTrue(); + + // pre-allocate set on task. + when(task.getSetPreAllocateLength()).thenReturn(false); + assertThat(strategy.isPreAllocateLength(task)).isFalse(); + + when(task.getSetPreAllocateLength()).thenReturn(true); + assertThat(strategy.isPreAllocateLength(task)).isTrue(); + + // pre-allocate set on task is true but can't support seek. + when(factory.supportSeek()).thenReturn(false); + assertThat(strategy.isPreAllocateLength(task)).isFalse(); } } \ No newline at end of file