package gov.nysenate.openleg.util;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.*;
import org.springframework.core.io.UrlResource;
import java.io.*;
import java.util.*;
public class FileIOUtils
{
/**
* Returns a collection of files sorted by file name (not file path!)
*
* @param directory - The directory to get files from.
* @param recursive - true to retrieve files from sub-directories.
* @return Collection<File>
* @throws java.io.IOException
*/
public static Collection<File> getSortedFiles(File directory, boolean recursive, String[] excludeDirs)
throws IOException {
Collection<File> files = safeListFiles(directory, recursive, excludeDirs);
Collections.sort((List<File>) files, new Comparator<File>() {
public int compare(File a, File b) {
return a.getName().compareTo(b.getName());
}
});
return files;
}
/**
* Any directory that we attempt to list files from should exist. If it doesn't then
* create them. This makes the processes robust against incomplete environment setups.
*
* @param directory - The directory to list files from (and create if necessary)
* @param extensions - A list of extensions to grab. null for all extensions.
* @param recursive - true when you want to list files recursively.
* @return A collection of matching filenames
* @throws IOException
*/
public static Collection<File> safeListFiles(File directory, String[] extensions, boolean recursive) throws IOException {
FileUtils.forceMkdir(directory);
return FileUtils.listFiles(directory, extensions, recursive);
}
/**
* Any directory that we attempt to list files from should exist. If it doesn't then
* create them. This overload can be used to exclude certain directories if recursive is true.
*
* @param directory - The directory to list files from (and create if necessary)
* @param recursive - true when you want to list files recursively.
* @param excludeDirs - Array of directory names that should be excluded from the match.
* Set to null if all directories should be matched.
* @return A collection of matching filenames
* @throws IOException
*/
public static Collection<File> safeListFiles(File directory, boolean recursive, String[] excludeDirs) throws IOException {
FileUtils.forceMkdir(directory);
IOFileFilter dirFileFilter;
if (excludeDirs != null && excludeDirs.length > 0) {
List<IOFileFilter> excludeDirFilters = new ArrayList<>();
for (String excludeDir : excludeDirs) {
excludeDirFilters.add(FileFilterUtils.nameFileFilter(excludeDir));
}
dirFileFilter = FileFilterUtils.notFileFilter(new OrFileFilter(excludeDirFilters));
}
else {
dirFileFilter = (recursive) ? TrueFileFilter.TRUE : FalseFileFilter.FALSE;
}
return FileUtils.listFiles(directory, TrueFileFilter.TRUE, dirFileFilter);
}
/**
* Create the specified folder if necessary and return a File handle to it.
*
* @param parent - The parent directory for this folder
* @param folderName - The name of the directory to retrieve
* @return a File handle to the requested folder.
* @throws IOException
*/
public static File safeGetFolder(File parent, String folderName) throws IOException {
File directory = new File(parent, folderName);
FileUtils.forceMkdir(directory);
return directory;
}
/**
* Moves a file, deleting the destination file if it already exists.
*
* @param file File
* @param directory File
* @param createDirectory ?
* @throws IOException
*/
public static void moveFileToDirectory(File file, File directory, boolean createDirectory) throws IOException {
File newFile = new File(directory, file.getName());
if (newFile.exists()) {
newFile.delete();
}
FileUtils.moveFileToDirectory(file, directory, true);
}
/**
* Writes out an InputStream to the destination file path specified.
*
* @param stuffToWrite InputStream
* @param destinationPath String
* @throws IOException
*/
public static void writeToFile(InputStream stuffToWrite, String destinationPath) throws IOException {
OutputStream os = new FileOutputStream(destinationPath);
byte[] b = new byte[2048];
int length;
while ((length = stuffToWrite.read(b)) != -1) {
os.write(b, 0, length);
}
stuffToWrite.close();
os.close();
}
public static boolean isFileClosed(File file) throws IOException {
Process plsof = null;
BufferedReader reader = null;
try {
plsof = new ProcessBuilder(new String[]{"lsof", "|", "grep", file.getAbsolutePath()}).start();
reader = new BufferedReader(new InputStreamReader(plsof.getInputStream()));
String line;
while((line=reader.readLine())!=null) {
if(line.contains(file.getAbsolutePath())) {
reader.close();
plsof.destroy();
return false;
}
}
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException ignored) {}
Optional.ofNullable(plsof).ifPresent(Process::destroy);
}
return true;
}
}