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.
This commit is contained in:
Samoylenko Dmitry 2020-11-03 15:15:33 +03:00
parent e139a4652a
commit 99ddb4037b

View file

@ -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);