FileUtils { @NonNull public static String getValidFileName( @NonNull String baseName, @NonNull String extension, @NonNull File directory) throws IOException { String fileName = (extension.isEmpty() ? baseName : (baseName + "." + extension)); String validBaseName = baseName.replaceAll("[^a-zA-Z0-9]", "_"); String validExtension = extension.replaceAll("[^a-zA-Z0-9]", "_"); String validExtensionWithDot = (validExtension.isEmpty() ? "" : ("." + validExtension)); String validFileName = validBaseName + validExtensionWithDot; String fileHash = Hashing.sha1().hashString(fileName, StandardCharsets.UTF_8).toString(); if (!validFileName.equals(fileName)) { validFileName = validBaseName + "_" + fileHash + validExtensionWithDot; } if (isFilePathTooLong(validFileName, directory)) { validFileName = fileHash + validExtensionWithDot; if (isFilePathTooLong(validFileName, directory)) { throw new IOException("File name or file path is too long: " + new File(directory, validFileName).getAbsolutePath()); } } return validFileName; } 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 testGetValidFileName() throws IOException { File directory = new File("/Users/foo"); assertThat(FileUtils.getValidFileName("foo", "txt", directory)).isEqualTo("foo.txt"); assertThat( FileUtils.getValidFileName( "com.android.support/design/23.3.0/jars/classes.jar" + "_build=23.0_jumbo=false_multidex=true_optimize=false", "jar", directory)) .isEqualTo( "com_android_support_design_23_3_0_jars_classes_jar" + "_build_23_0_jumbo_false_multidex_true_optimize_false" + "_0979f3a79bbb13e755cfaa70190a4dbc116600f5.jar"); assertThat( FileUtils.getValidFileName( "com.android.support\\design\\23.3.0\\jars\\classes.jar" + "_build=23.0_jumbo=false_multidex=true_optimize=false", "jar", directory)) .isEqualTo( "com_android_support_design_23_3_0_jars_classes_jar" + "_build_23_0_jumbo_false_multidex_true_optimize_false" + "_48d7fda3351450337c26a2990bef21df95f65685.jar"); assertThat( FileUtils.getValidFileName( "foo`-=[]\\\\;',./~!@#$%^&*()_+{}|:\\\"<>?", "...!@#", directory)) .isEqualTo( "foo__________________________________" + "_387e0d11003e554ddceaeca12af15839dbd51643.______"); assertThat(FileUtils.getValidFileName("foo", "", directory)).isEqualTo("foo"); assertThat(FileUtils.getValidFileName(Strings.repeat("a", 252), "txt", directory)) .isEqualTo("7d872a53e320bcdb5adce13b87a7e7671fef6780.txt"); try { FileUtils.getValidFileName("foo", "txt", new File("/", Strings.repeat("a", 4088))); fail("expected IOException"); } catch (IOException exception) { assertTrue(exception.getMessage().startsWith("File name or file path is too long: ")); } }