Search in sources :

Example 1 with DiskCacheFile

use of org.xutils.cache.DiskCacheFile in project xUtils3 by wyouflf.

the class FileLoader method load.

@Override
public File load(final InputStream in) throws Throwable {
    File targetFile = null;
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        targetFile = new File(tempSaveFilePath);
        if (targetFile.isDirectory()) {
            // 防止文件正在写入时, 父文件夹被删除, 继续写入时造成偶现文件节点异常问题.
            IOUtil.deleteFileOrDir(targetFile);
        }
        if (!targetFile.exists()) {
            File dir = targetFile.getParentFile();
            if (!dir.exists() && !dir.mkdirs()) {
                throw new IOException("can not create dir: " + dir.getAbsolutePath());
            }
        }
        // 处理[断点逻辑2](见文件头doc)
        long targetFileLen = targetFile.length();
        if (isAutoResume && targetFileLen > 0) {
            FileInputStream fis = null;
            try {
                long filePos = targetFileLen - CHECK_SIZE;
                if (filePos > 0) {
                    fis = new FileInputStream(targetFile);
                    byte[] fileCheckBuffer = IOUtil.readBytes(fis, filePos, CHECK_SIZE);
                    byte[] checkBuffer = IOUtil.readBytes(in, 0, CHECK_SIZE);
                    if (!Arrays.equals(checkBuffer, fileCheckBuffer)) {
                        // 先关闭文件流, 否则文件删除会失败.
                        IOUtil.closeQuietly(fis);
                        IOUtil.deleteFileOrDir(targetFile);
                        throw new RuntimeException("need retry");
                    } else {
                        contentLength -= CHECK_SIZE;
                    }
                } else {
                    IOUtil.deleteFileOrDir(targetFile);
                    throw new RuntimeException("need retry");
                }
            } finally {
                IOUtil.closeQuietly(fis);
            }
        }
        // 开始下载
        long current = 0;
        FileOutputStream fileOutputStream = null;
        if (isAutoResume) {
            current = targetFileLen;
            fileOutputStream = new FileOutputStream(targetFile, true);
        } else {
            fileOutputStream = new FileOutputStream(targetFile);
        }
        long total = contentLength + current;
        bis = new BufferedInputStream(in);
        bos = new BufferedOutputStream(fileOutputStream);
        if (progressHandler != null && !progressHandler.updateProgress(total, current, true)) {
            throw new Callback.CancelledException("download stopped!");
        }
        byte[] tmp = new byte[4096];
        int len;
        while ((len = bis.read(tmp)) != -1) {
            // 防止父文件夹被其他进程删除, 继续写入时造成父文件夹变为0字节文件的问题.
            if (!targetFile.getParentFile().exists()) {
                targetFile.getParentFile().mkdirs();
                throw new IOException("parent be deleted!");
            }
            bos.write(tmp, 0, len);
            current += len;
            if (progressHandler != null) {
                if (!progressHandler.updateProgress(total, current, false)) {
                    bos.flush();
                    throw new Callback.CancelledException("download stopped!");
                }
            }
        }
        bos.flush();
        // 处理[下载逻辑2.a](见文件头doc)
        if (diskCacheFile != null) {
            targetFile = diskCacheFile.commit();
        }
        if (progressHandler != null) {
            progressHandler.updateProgress(total, current, true);
        }
    } finally {
        IOUtil.closeQuietly(bis);
        IOUtil.closeQuietly(bos);
    }
    return autoRename(targetFile);
}
Also used : BufferedInputStream(java.io.BufferedInputStream) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) File(java.io.File) DiskCacheFile(org.xutils.cache.DiskCacheFile) BufferedOutputStream(java.io.BufferedOutputStream) FileInputStream(java.io.FileInputStream)

Example 2 with DiskCacheFile

use of org.xutils.cache.DiskCacheFile in project xUtils3 by wyouflf.

the class ImageDecoder method getThumbCache.

/**
     * 根据文件的修改时间和图片的属性获取缩略图
     *
     * @param file
     * @param options
     * @return
     */
private static Bitmap getThumbCache(File file, ImageOptions options) {
    if (!WebPFactory.available())
        return null;
    DiskCacheFile cacheFile = null;
    try {
        cacheFile = THUMB_CACHE.getDiskCacheFile(file.getAbsolutePath() + "@" + file.lastModified() + options.toString());
        if (cacheFile != null && cacheFile.exists()) {
            BitmapFactory.Options bitmapOps = new BitmapFactory.Options();
            bitmapOps.inJustDecodeBounds = false;
            bitmapOps.inPurgeable = true;
            bitmapOps.inInputShareable = true;
            bitmapOps.inPreferredConfig = Bitmap.Config.ARGB_8888;
            return WebPFactory.decodeFile(cacheFile.getAbsolutePath(), bitmapOps);
        }
    } catch (Throwable ex) {
        LogUtil.w(ex.getMessage(), ex);
    } finally {
        IOUtil.closeQuietly(cacheFile);
    }
    return null;
}
Also used : DiskCacheFile(org.xutils.cache.DiskCacheFile) BitmapFactory(android.graphics.BitmapFactory)

Example 3 with DiskCacheFile

use of org.xutils.cache.DiskCacheFile in project xUtils3 by wyouflf.

the class ImageDecoder method saveThumbCache.

/**
     * 根据文件的修改时间和图片的属性保存缩略图
     *
     * @param file
     * @param options
     * @param thumbBitmap
     */
private static void saveThumbCache(File file, ImageOptions options, Bitmap thumbBitmap) {
    if (!WebPFactory.available())
        return;
    DiskCacheEntity entity = new DiskCacheEntity();
    entity.setKey(file.getAbsolutePath() + "@" + file.lastModified() + options.toString());
    DiskCacheFile cacheFile = null;
    OutputStream out = null;
    try {
        cacheFile = THUMB_CACHE.createDiskCacheFile(entity);
        if (cacheFile != null) {
            out = new FileOutputStream(cacheFile);
            byte[] encoded = WebPFactory.encodeBitmap(thumbBitmap, 80);
            out.write(encoded);
            out.flush();
            cacheFile = cacheFile.commit();
        }
    } catch (Throwable ex) {
        IOUtil.deleteFileOrDir(cacheFile);
        LogUtil.w(ex.getMessage(), ex);
    } finally {
        IOUtil.closeQuietly(cacheFile);
        IOUtil.closeQuietly(out);
    }
}
Also used : DiskCacheFile(org.xutils.cache.DiskCacheFile) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) FileOutputStream(java.io.FileOutputStream) DiskCacheEntity(org.xutils.cache.DiskCacheEntity)

Example 4 with DiskCacheFile

use of org.xutils.cache.DiskCacheFile in project xUtils3 by wyouflf.

the class FileLoader method load.

@Override
public File load(final UriRequest request) throws Throwable {
    ProcessLock processLock = null;
    File result = null;
    try {
        // 处理[下载逻辑1](见文件头doc)
        saveFilePath = params.getSaveFilePath();
        diskCacheFile = null;
        if (TextUtils.isEmpty(saveFilePath)) {
            if (progressHandler != null && !progressHandler.updateProgress(0, 0, false)) {
                throw new Callback.CancelledException("download stopped!");
            }
            // 保存路径为空, 存入磁盘缓存.
            initDiskCacheFile(request);
        } else {
            tempSaveFilePath = saveFilePath + ".tmp";
        }
        if (progressHandler != null && !progressHandler.updateProgress(0, 0, false)) {
            throw new Callback.CancelledException("download stopped!");
        }
        // 等待, 若不能下载则取消此次下载.
        processLock = ProcessLock.tryLock(saveFilePath + "_lock", true);
        if (processLock == null || !processLock.isValid()) {
            throw new FileLockedException("download exists: " + saveFilePath);
        }
        params = request.getParams();
        {
            // 处理[断点逻辑1](见文件头doc)
            long range = 0;
            if (isAutoResume) {
                File tempFile = new File(tempSaveFilePath);
                long fileLen = tempFile.length();
                if (fileLen <= CHECK_SIZE) {
                    IOUtil.deleteFileOrDir(tempFile);
                    range = 0;
                } else {
                    range = fileLen - CHECK_SIZE;
                }
            }
            // retry 时需要覆盖RANGE参数
            params.setHeader("RANGE", "bytes=" + range + "-");
        }
        if (progressHandler != null && !progressHandler.updateProgress(0, 0, false)) {
            throw new Callback.CancelledException("download stopped!");
        }
        // may be throw an HttpException
        request.sendRequest();
        contentLength = request.getContentLength();
        if (isAutoRename) {
            responseFileName = getResponseFileName(request);
        }
        if (isAutoResume) {
            isAutoResume = isSupportRange(request);
        }
        if (progressHandler != null && !progressHandler.updateProgress(0, 0, false)) {
            throw new Callback.CancelledException("download stopped!");
        }
        if (diskCacheFile != null) {
            DiskCacheEntity entity = diskCacheFile.getCacheEntity();
            entity.setLastAccess(System.currentTimeMillis());
            entity.setEtag(request.getETag());
            entity.setExpires(request.getExpiration());
            entity.setLastModify(new Date(request.getLastModified()));
        }
        result = this.load(request.getInputStream());
    } catch (HttpException httpException) {
        if (httpException.getCode() == 416) {
            if (diskCacheFile != null) {
                result = diskCacheFile.commit();
            } else {
                result = new File(tempSaveFilePath);
            }
            // 从缓存获取文件, 不rename和断点, 直接退出.
            if (result != null && result.exists()) {
                if (isAutoRename) {
                    responseFileName = getResponseFileName(request);
                }
                result = autoRename(result);
            } else {
                IOUtil.deleteFileOrDir(result);
                throw new IllegalStateException("cache file not found" + request.getCacheKey());
            }
        } else {
            throw httpException;
        }
    } finally {
        IOUtil.closeQuietly(processLock);
        IOUtil.closeQuietly(diskCacheFile);
    }
    return result;
}
Also used : FileLockedException(org.xutils.ex.FileLockedException) ProcessLock(org.xutils.common.util.ProcessLock) HttpException(org.xutils.ex.HttpException) DiskCacheEntity(org.xutils.cache.DiskCacheEntity) File(java.io.File) DiskCacheFile(org.xutils.cache.DiskCacheFile) Date(java.util.Date)

Aggregations

DiskCacheFile (org.xutils.cache.DiskCacheFile)4 File (java.io.File)2 FileOutputStream (java.io.FileOutputStream)2 DiskCacheEntity (org.xutils.cache.DiskCacheEntity)2 BitmapFactory (android.graphics.BitmapFactory)1 BufferedInputStream (java.io.BufferedInputStream)1 BufferedOutputStream (java.io.BufferedOutputStream)1 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 Date (java.util.Date)1 ProcessLock (org.xutils.common.util.ProcessLock)1 FileLockedException (org.xutils.ex.FileLockedException)1 HttpException (org.xutils.ex.HttpException)1