package net.knarcraft.ffmpegconverter.utility; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * A helper class for dealing with files */ @SuppressWarnings("unused") public final class FileHelper { private FileHelper() { } /** * Gets a buffered reader for an internal file * * @param file

The name of the file to get a buffered reader for (start with a '/'). The file should reside in * the resources directory.

* @return

A buffered read for reading the file

* @throws FileNotFoundException

If unable to get an input stream for the given file

*/ @NotNull public static BufferedReader getBufferedReaderForInternalFile(@NotNull String file) throws FileNotFoundException { InputStream inputStream = getInputStreamForInternalFile(file); if (inputStream == null) { throw new FileNotFoundException("Unable to read the given file"); } return getBufferedReaderFromInputStream(inputStream); } /** * Gets an input stream from a string pointing to an internal file * *

This is used for getting an input stream for reading a file contained within the compiled .jar file. The file * should be in the resources directory, and the file path should start with a forward slash ("/") character.

* * @param file

The file to read

* @return

An input stream for the file

*/ @Nullable public static InputStream getInputStreamForInternalFile(@NotNull String file) { return FileHelper.class.getResourceAsStream(file); } /** * Gets a buffered reader from a string pointing to a file * * @param file

The file to read

* @return

A buffered reader reading the file

* @throws FileNotFoundException

If the given file does not exist

*/ @NotNull public static BufferedReader getBufferedReaderFromString(@NotNull String file) throws FileNotFoundException { FileInputStream fileInputStream = new FileInputStream(file); return getBufferedReaderFromInputStream(fileInputStream); } /** * Gets a buffered reader given an input stream * * @param inputStream

The input stream to read

* @return

A buffered reader reading the input stream

*/ @NotNull public static BufferedReader getBufferedReaderFromInputStream(@NotNull InputStream inputStream) { InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); return new BufferedReader(inputStreamReader); } /** * Gets a buffered writer from a string pointing to a file * * @param file

The file to write to

* @return

A buffered writer writing to the file

* @throws FileNotFoundException

If the file does not exist

*/ @NotNull public static BufferedWriter getBufferedWriterFromString(@NotNull String file) throws FileNotFoundException { FileOutputStream fileOutputStream = new FileOutputStream(file); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8); return new BufferedWriter(outputStreamWriter); } /** * Reads key/value pairs from a buffered reader * * @param bufferedReader

The buffered reader to read

* @param separator

The separator separating a key from a value

* @return

A map containing the read pairs

* @throws IOException

If unable to read from the stream

*/ @NotNull public static Map readKeyValuePairs(@NotNull BufferedReader bufferedReader, @NotNull String separator) throws IOException { Map readPairs = new HashMap<>(); List lines = readLines(bufferedReader); for (String line : lines) { int separatorIndex = line.indexOf(separator); if (separatorIndex == -1) { continue; } //Read the line String key = line.substring(0, separatorIndex); String value = line.substring(separatorIndex + 1); readPairs.put(key, value); } return readPairs; } /** * Reads a list from a buffered reader * * @param bufferedReader

The buffered reader to read

* @return

A list of the read strings

* @throws IOException

If unable to read from the stream

*/ @NotNull public static List readLines(@NotNull BufferedReader bufferedReader) throws IOException { List readLines = new ArrayList<>(); String line = bufferedReader.readLine(); boolean firstLine = true; while (line != null) { //Strip UTF BOM from the first line if (firstLine) { line = removeUTF8BOM(line); firstLine = false; } //Split at first separator if (line.isEmpty()) { line = bufferedReader.readLine(); continue; } readLines.add(line); line = bufferedReader.readLine(); } bufferedReader.close(); return readLines; } /** * Removes the UTF-8 Byte Order Mark if present * * @param string

The string to remove the BOM from

* @return

A string guaranteed without a BOM

*/ private static @NotNull String removeUTF8BOM(@NotNull String string) { String UTF8_BOM = "\uFEFF"; if (string.startsWith(UTF8_BOM)) { string = string.substring(1); } return string; } }