Search in sources :

Example 1 with FileDownloadOutputStream

use of com.liulishuo.filedownloader.stream.FileDownloadOutputStream in project FileDownloader by lingochamp.

the class FileDownloadRunnable method fetch.

/**
     * @return Whether finish looper or not.
     */
@SuppressWarnings("SameReturnValue")
private boolean fetch(FileDownloadConnection connection, boolean isSucceedContinue, long soFar, long total) throws Throwable {
    // fetching datum
    InputStream inputStream = null;
    final FileDownloadOutputStream outputStream = getOutputStream(isSucceedContinue, total);
    try {
        // Step 1, get input stream
        inputStream = connection.getInputStream();
        byte[] buff = new byte[BUFFER_SIZE];
        callbackMinIntervalBytes = calculateCallbackMinIntervalBytes(total, maxProgressCount);
        // enter fetching loop(Step 2->6)
        do {
            // Step 2, read from input stream.
            int byteCount = inputStream.read(buff);
            if (byteCount == -1) {
                break;
            }
            //                if (FileDownloadLog.NEED_LOG) {
            //                    startWriteNanoTime = System.nanoTime();
            //                }
            // Step 3, writ to file
            outputStream.write(buff, 0, byteCount);
            //                if (FileDownloadLog.NEED_LOG) {
            //                    currentNanoTime = System.nanoTime();
            //                    long writeConsume = currentNanoTime - startWriteNanoTime;
            //                    if (latestWriteNanoTime != 0) {
            //                        FileDownloadLog.v(this, "each fetch loop consume | write consume: | %fms | %fms",
            //                                (currentNanoTime - latestWriteNanoTime - writeConsume) / 1000000f,
            //                                writeConsume / 1000000f);
            //                    }
            //                    latestWriteNanoTime = currentNanoTime;
            //                }
            // Step 4, adapter sofar
            soFar += byteCount;
            // Step 5, callback on progressing
            onProgress(soFar, total, outputStream);
            // Step 6, check state
            if (checkState()) {
                // callback on paused
                onPause();
                return true;
            }
        } while (true);
        // Step 7, adapter chunked transfer encoding
        if (total == TOTAL_VALUE_IN_CHUNKED_RESOURCE) {
            total = soFar;
        }
        // Step 8, Compare between the downloaded so far bytes with the total bytes.
        if (soFar == total) {
            // Step 9, rename the temp file to the completed file.
            renameTempFile();
            // Step 10, remove data from DB.
            helper.remove(mId);
            // callback completed
            onComplete(total);
            return true;
        } else {
            throw new RuntimeException(FileDownloadUtils.formatString("sofar[%d] not equal total[%d]", soFar, total));
        }
    } finally {
        if (inputStream != null) {
            //noinspection ThrowFromFinallyBlock
            inputStream.close();
        }
        try {
            if (outputStream != null) {
                //noinspection ThrowFromFinallyBlock
                outputStream.sync();
            }
        } finally {
            //noinspection ConstantConditions
            if (outputStream != null) {
                //noinspection ThrowFromFinallyBlock
                outputStream.close();
            }
        }
    }
}
Also used : InputStream(java.io.InputStream) FileDownloadOutputStream(com.liulishuo.filedownloader.stream.FileDownloadOutputStream)

Example 2 with FileDownloadOutputStream

use of com.liulishuo.filedownloader.stream.FileDownloadOutputStream in project FileDownloader by lingochamp.

the class DownloadLaunchRunnable method handlePreAllocate.

private void handlePreAllocate(long totalLength, String path) throws IOException, IllegalAccessException {
    FileDownloadOutputStream outputStream = null;
    try {
        if (totalLength != TOTAL_VALUE_IN_CHUNKED_RESOURCE) {
            outputStream = FileDownloadUtils.createOutputStream(model.getTempFilePath());
            final long breakpointBytes = new File(path).length();
            final long requiredSpaceBytes = totalLength - breakpointBytes;
            final long freeSpaceBytes = FileDownloadUtils.getFreeSpaceBytes(path);
            if (freeSpaceBytes < requiredSpaceBytes) {
                // throw a out of space exception.
                throw new FileDownloadOutOfSpaceException(freeSpaceBytes, requiredSpaceBytes, breakpointBytes);
            } else if (!FileDownloadProperties.getImpl().fileNonPreAllocation) {
                // pre allocate.
                outputStream.setLength(totalLength);
            }
        }
    } finally {
        if (outputStream != null)
            outputStream.close();
    }
}
Also used : FileDownloadOutOfSpaceException(com.liulishuo.filedownloader.exception.FileDownloadOutOfSpaceException) FileDownloadOutputStream(com.liulishuo.filedownloader.stream.FileDownloadOutputStream) File(java.io.File)

Example 3 with FileDownloadOutputStream

use of com.liulishuo.filedownloader.stream.FileDownloadOutputStream in project FileDownloader by lingochamp.

the class FileDownloadRunnable method getOutputStream.

// ----------------------------------
private FileDownloadOutputStream getOutputStream(final boolean append, final long totalBytes) throws IOException, IllegalAccessException {
    final String tempPath = model.getTempFilePath();
    if (TextUtils.isEmpty(tempPath)) {
        throw new RuntimeException("found invalid internal destination path, empty");
    }
    //noinspection ConstantConditions
    if (!FileDownloadUtils.isFilenameValid(tempPath)) {
        throw new RuntimeException(FileDownloadUtils.formatString("found invalid internal destination filename" + " %s", tempPath));
    }
    File file = new File(tempPath);
    if (file.exists() && file.isDirectory()) {
        throw new RuntimeException(FileDownloadUtils.formatString("found invalid internal destination path[%s]," + " & path is directory[%B]", tempPath, file.isDirectory()));
    }
    if (!file.exists()) {
        if (!file.createNewFile()) {
            throw new IOException(FileDownloadUtils.formatString("create new file error  %s", file.getAbsolutePath()));
        }
    }
    FileDownloadOutputStream outputStream = mOutputStreamCreator.create(file);
    // check the available space bytes whether enough or not.
    if (totalBytes > 0) {
        final long breakpointBytes = file.length();
        final long requiredSpaceBytes = totalBytes - breakpointBytes;
        final long freeSpaceBytes = FileDownloadUtils.getFreeSpaceBytes(tempPath);
        if (freeSpaceBytes < requiredSpaceBytes) {
            outputStream.close();
            // throw a out of space exception.
            throw new FileDownloadOutOfSpaceException(freeSpaceBytes, requiredSpaceBytes, breakpointBytes);
        } else if (!FileDownloadProperties.getImpl().FILE_NON_PRE_ALLOCATION) {
            // pre allocate.
            outputStream.setLength(totalBytes);
        }
    }
    if (append && mOutputStreamCreator.supportSeek()) {
        outputStream.seek(model.getSoFar());
    }
    return outputStream;
}
Also used : FileDownloadOutOfSpaceException(com.liulishuo.filedownloader.exception.FileDownloadOutOfSpaceException) IOException(java.io.IOException) FileDownloadOutputStream(com.liulishuo.filedownloader.stream.FileDownloadOutputStream) File(java.io.File)

Example 4 with FileDownloadOutputStream

use of com.liulishuo.filedownloader.stream.FileDownloadOutputStream in project FileDownloader by lingochamp.

the class FetchDataTask method run.

public void run() throws IOException, IllegalAccessException, IllegalArgumentException, FileDownloadGiveUpRetryException {
    if (paused)
        return;
    long contentLength = FileDownloadUtils.findContentLength(connectionIndex, connection);
    if (contentLength == TOTAL_VALUE_IN_CHUNKED_RESOURCE) {
        contentLength = FileDownloadUtils.findContentLengthFromContentRange(connection);
    }
    if (contentLength == 0) {
        throw new FileDownloadGiveUpRetryException(FileDownloadUtils.formatString("there isn't any content need to download on %d-%d with the " + "content-length is 0", downloadId, connectionIndex));
    }
    if (this.contentLength > 0 && contentLength != this.contentLength) {
        final String range;
        if (endOffset == ConnectionProfile.RANGE_INFINITE) {
            range = FileDownloadUtils.formatString("range[%d-)", currentOffset);
        } else {
            range = FileDownloadUtils.formatString("range[%d-%d)", currentOffset, endOffset);
        }
        throw new FileDownloadGiveUpRetryException(FileDownloadUtils.formatString("require %s with contentLength(%d), but the " + "backend response contentLength is %d on " + "downloadId[%d]-connectionIndex[%d], please ask your backend " + "dev to fix such problem.", range, this.contentLength, contentLength, downloadId, connectionIndex));
    }
    final long fetchBeginOffset = currentOffset;
    // start fetch
    InputStream inputStream = null;
    FileDownloadOutputStream outputStream = null;
    try {
        final boolean isSupportSeek = CustomComponentHolder.getImpl().isSupportSeek();
        if (hostRunnable != null && !isSupportSeek) {
            throw new IllegalAccessException("can't using multi-download when the output stream can't support seek");
        }
        this.outputStream = outputStream = FileDownloadUtils.createOutputStream(path);
        if (isSupportSeek) {
            outputStream.seek(currentOffset);
        }
        if (FileDownloadLog.NEED_LOG) {
            FileDownloadLog.d(this, "start fetch(%d): range [%d, %d), seek to[%d]", connectionIndex, startOffset, endOffset, currentOffset);
        }
        inputStream = connection.getInputStream();
        byte[] buff = new byte[BUFFER_SIZE];
        if (paused)
            return;
        do {
            int byteCount = inputStream.read(buff);
            if (byteCount == -1) {
                break;
            }
            outputStream.write(buff, 0, byteCount);
            currentOffset += byteCount;
            // callback progress
            callback.onProgress(byteCount);
            checkAndSync();
            // check status
            if (paused)
                return;
            if (isWifiRequired && FileDownloadUtils.isNetworkNotOnWifiType()) {
                throw new FileDownloadNetworkPolicyException();
            }
        } while (true);
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            if (outputStream != null)
                sync();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    final long fetchedLength = currentOffset - fetchBeginOffset;
    if (contentLength != TOTAL_VALUE_IN_CHUNKED_RESOURCE && contentLength != fetchedLength) {
        throw new FileDownloadGiveUpRetryException(FileDownloadUtils.formatString("fetched length[%d] != content length[%d]," + " range[%d, %d) offset[%d] fetch begin offset[%d]", fetchedLength, contentLength, startOffset, endOffset, currentOffset, fetchBeginOffset));
    }
    // callback completed
    callback.onCompleted(hostRunnable, startOffset, endOffset);
}
Also used : FileDownloadGiveUpRetryException(com.liulishuo.filedownloader.exception.FileDownloadGiveUpRetryException) InputStream(java.io.InputStream) FileDownloadOutputStream(com.liulishuo.filedownloader.stream.FileDownloadOutputStream) IOException(java.io.IOException) FileDownloadNetworkPolicyException(com.liulishuo.filedownloader.exception.FileDownloadNetworkPolicyException)

Aggregations

FileDownloadOutputStream (com.liulishuo.filedownloader.stream.FileDownloadOutputStream)4 FileDownloadOutOfSpaceException (com.liulishuo.filedownloader.exception.FileDownloadOutOfSpaceException)2 File (java.io.File)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 FileDownloadGiveUpRetryException (com.liulishuo.filedownloader.exception.FileDownloadGiveUpRetryException)1 FileDownloadNetworkPolicyException (com.liulishuo.filedownloader.exception.FileDownloadNetworkPolicyException)1