find virtual file for relative path under content roots


Given a relative path, eg foo/, is it possible to search each content root in the project for that relative path and thus arrive at a VirtualFile? This will be a complete path under a content entry, so FileNameIndex etc I don't think is useful here, as that's for searching by name.

I can iterate the content roots of course, but I imagined there must be some utility method already written for this.

cheers, jamie

Comment actions Permalink

I extracted the code I use in my plugin to find files.

It compiles but you will need to debug it for specific conditions like fileType not found or invalid parameters:

public class PsiUtils {
    public static List<VirtualFile> findFileByRelativePath(@NotNull Project project, @NotNull String fileRelativePath) {
       String relativePath = fileRelativePath.startsWith("/") ? fileRelativePath : "/" + fileRelativePath;
       Set<FileType> fileTypes = Collections.singleton(FileTypeManager.getInstance().getFileTypeByFileName(relativePath));
       final List<VirtualFile> fileList = new ArrayList<>();
       FileBasedIndex.getInstance().processFilesContainingAllKeys(FileTypeIndex.NAME, fileTypes, GlobalSearchScope.projectScope(project), null, virtualFile -> {
          if (virtualFile.getPath().endsWith(relativePath)) {
          return true;
       return fileList;
Comment actions Permalink

Thanks Vladimir... I iterated the content entries for each module, which works ok.

Your way may well be better... I'll bear it in mind.

Thanks again.

Comment actions Permalink

I think u need use than "/" for support other platforms like Mac OS.

Comment actions Permalink

VirtualFile uses '/' as the separator:


* Gets the path of this file. Path is a string which uniquely identifies file within given
* <code>{@link VirtualFileSystem}</code>. Format of the path depends on the concrete file system.
* For <code>{@link com.intellij.openapi.vfs.LocalFileSystem}</code> it is an absolute file path with file separator characters
* (File.separatorChar) replaced to the forward slash ('/').
* @return the path
public abstract String getPath();



Comment actions Permalink

Just chiming in to say this was super useful. Thanks Vladimir!


Please sign in to leave a comment.