From 99ddb4037bb658b3ecf4860514b7bc7750803310 Mon Sep 17 00:00:00 2001 From: Samoylenko Dmitry Date: Tue, 3 Nov 2020 15:15:33 +0300 Subject: [PATCH] Correctly handling Exception: java.nio.file.FileSystemException: No space left on device. By default methods File.makeDir() and File.makeDirs() can return 'false' if file aleady exists or can not be created. Such silent ignore of the situation propagates misbehavior to the caller: CacheDataSink#173 : new FileOutputStream(file). And then it throws not correct exception type 'FileNotFoundException'. While correct exception should be 'no space left on the device'. This can be fixed only with 'Files.createDirectories()' method that throws correct exception type. --- .../upstream/cache/SimpleCache.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java index 29c09ff486..db911a30fd 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.upstream.cache; +import android.os.Build; import android.os.ConditionVariable; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -26,6 +27,7 @@ import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Util; import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; @@ -410,14 +412,30 @@ public final class SimpleCache implements Cache { Assertions.checkState(cachedContent.isFullyLocked(position, length)); if (!cacheDir.exists()) { // For some reason the cache directory doesn't exist. Make a best effort to create it. - cacheDir.mkdirs(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + try { + Files.createDirectories(cacheDir.toPath()); + } catch (IOException e) { + throw new CacheException(e); + } + } else { + cacheDir.mkdirs(); + } removeStaleSpans(); } evictor.onStartFile(this, key, position, length); // Randomly distribute files into subdirectories with a uniform distribution. File fileDir = new File(cacheDir, Integer.toString(random.nextInt(SUBDIRECTORY_COUNT))); if (!fileDir.exists()) { - fileDir.mkdir(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + try { + Files.createDirectories(fileDir.toPath()); + } catch (IOException e) { + throw new CacheException(e); + } + } else { + fileDir.mkdir(); + } } long lastTouchTimestamp = System.currentTimeMillis(); return SimpleCacheSpan.getCacheFile(fileDir, cachedContent.id, position, lastTouchTimestamp);