CarGuo/GSYVideoPlayer · error · IOException

File %s is not directory!

Error message

File %s is not directory!

What it means

Files.makeDir's second failure mode: when the directory does not exist and mkdirs() returns false (or silently raced), it throws IOException('Directory <path> can't be created'). This is the generic 'cannot create cache directory' error surfaced through FileCache as ProxyCacheException.

Source

Thrown at gsyVideoPlayer-proxy_cache/src/main/java/com/danikula/videocache/file/Files.java:26

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * Utils for work with files.
 *
 * @author Alexey Danilov (danikula@gmail.com).
 */
class Files {


    static void makeDir(File directory) throws IOException {
        if (directory.exists()) {
            if (!directory.isDirectory()) {
                throw new IOException("File " + directory + " is not directory!");
            }
        } else {
            boolean isCreated = directory.mkdirs();
            if (!isCreated) {
                throw new IOException(String.format("Directory %s can't be created", directory.getAbsolutePath()));
            }
        }
    }

    static List<File> getLruListFiles(File directory) {
        List<File> result = new LinkedList<>();
        File[] files = directory.listFiles();
        if (files != null) {
            result = Arrays.asList(files);
            Collections.sort(result, new LastModifiedComparator());
        }
        return result;
    }

View on GitHub (pinned to e5d74d3aa9)

Solutions

  1. Switch to context.getCacheDir() or context.getExternalCacheDir() subdirectories
  2. Request WRITE_EXTERNAL_STORAGE (API <= 29) or use MANAGE_EXTERNAL_STORAGE/MediaStore appropriately
  3. Check Environment.getExternalStorageState() before using any external path
  4. Validate the whole parent chain is made of directories before building the proxy server

Example fix

// before
File cacheDir = new File(Environment.getExternalStorageDirectory(), "videocache");
new Builder(ctx).cacheDirectory(cacheDir).build();

// after
File base = ctx.getExternalCacheDir();
File cacheDir = (base != null) ? new File(base, "videocache") : new File(ctx.getCacheDir(), "videocache");
new Builder(ctx).cacheDirectory(cacheDir).build();
Defensive patterns

Strategy: validation

Validate before calling

File dir = ctx.getExternalCacheDir();
if (dir == null || !Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
    dir = ctx.getCacheDir(); // internal fallback
}
File cacheDir = new File(dir, "proxy");
if (!cacheDir.exists() && !cacheDir.mkdirs() && !cacheDir.isDirectory()) {
    throw new IOException("cannot prepare " + cacheDir);
}

Try / catch

catch (ProxyCacheException e) {
    if (String.valueOf(e.getMessage()).contains("is not directory")) {
        blockingPath.delete(); // remove the file occupying the dir path, then rebuild proxy
    } else throw e;
}

Prevention

When it happens

Trigger: mkdirs() fails due to missing write permission on the parent (scoped storage, external storage unmounted), a parent path component exists as a file, or disk/fs errors. Called from FileCache's constructor before opening the RandomAccessFile.

Common situations: Hardcoded /sdcard/... paths on Android 10+ without legacy storage; WRITE_EXTERNAL_STORAGE missing on API <= 29; cache dir on ejected SD card; parent path segment occupied by a file; SELinux-denied vendor paths.

Related errors


AI-assisted analysis of CarGuo/GSYVideoPlayer@e5d74d3aa9 (2026-08-14). Data as JSON: /api/errors/a103d9593147a422. Report an issue: GitHub.