FileUtils { @NonNull public static String relativePossiblyNonExistingPath(@NonNull File file, @NonNull File dir) { String path = dir.toURI().relativize(file.toURI()).getPath(); return toSystemDependentPath(path); } private  FileUtils(); static void deletePath(@NonNull final File path); static void deleteDirectoryContents(@NonNull final File directory); static void cleanOutputDir(@NonNull File path); static void copyFile(@NonNull File from, @NonNull File to); static void copyDirectory(@NonNull File from, @NonNull File to); static void copyFileToDirectory(@NonNull final File from, @NonNull final File to); static void copyDirectoryToDirectory(@NonNull final File from, @NonNull final File to); static void copyDirectoryContentToDirectory(
            @NonNull final File from, @NonNull final File to); @NonNull static File mkdirs(@NonNull File folder); static void delete(@NonNull File file); static void deleteIfExists(@NonNull File file); static void renameTo(@NonNull File file, @NonNull File to); @NonNull static File join(@NonNull File dir, @NonNull String... paths); @NonNull static File join(@NonNull File dir, @NonNull Iterable<String> paths); @NonNull static String join(@NonNull String... paths); @NonNull static String join(@NonNull Iterable<String> paths); @NonNull static String loadFileWithUnixLineSeparators(@NonNull File file); @NonNull static String relativePath(@NonNull File file, @NonNull File dir); @NonNull static String relativePossiblyNonExistingPath(@NonNull File file, @NonNull File dir); @NonNull static String toSystemDependentPath(@NonNull String path); @NonNull static String toSystemIndependentPath(@NonNull String path); @NonNull static String sha1(@NonNull File file); @NonNull static FluentIterable<File> getAllFiles(@NonNull File dir); @NonNull static String getNamesAsCommaSeparatedList(@NonNull Iterable<File> files); @NonNull static String getDirectoryNameForJar(@NonNull File inputFile); static void createFile(@NonNull File file, @NonNull String content); static List<File> find(@NonNull File base, @NonNull final Pattern pattern); static Optional<File> find(@NonNull File base, @NonNull final String name); @NonNull static byte[] readSegment(@NonNull File file, long start, int length); @NonNull static String joinFilePaths(@NonNull Iterable<File> files); @NonNull static String getValidFileName(
            @NonNull String baseName, @NonNull String extension, @NonNull File directory); static boolean isFileNameTooLong(@NonNull String fileName); static boolean isFilePathTooLong(@NonNull String fileName, @NonNull File directory);  }
@Test public void testRelativePossiblyNonExistingPath() throws IOException { File inputDir = new File("/folders/1/5/main"); File folder = new File(inputDir, "com/obsidian/v4/tv/home/playback"); File fileToProcess = new File(folder, "CameraPlaybackGlue$1.class"); assertEquals("com/obsidian/v4/tv/home/playback/CameraPlaybackGlue$1.class", FileUtils.relativePossiblyNonExistingPath(fileToProcess, inputDir)); fileToProcess = new File(folder, "CameraPlaybackGlue$CameraPlaybackHost.class"); assertEquals("com/obsidian/v4/tv/home/playback/CameraPlaybackGlue$CameraPlaybackHost.class", FileUtils.relativePossiblyNonExistingPath(fileToProcess, inputDir)); }