Read all .txt file inside a folder by it last edited time - java

I have a code here that can read all .txt file in 1 folder, it can print every content inside the .txt file to console. Then it moved to new folder.
The problem is: it has been read randomly, but i want to read the .txt file by it time-stamp, which is who have last edited time will be read at first...
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Basic {
public static void main(String[] args) throws IOException {
String source = "C:\\Users\\NN\\Documents\\Test1";
String target = "C:\\Users\\NN\\Documents\\Test2";
List<Path> filePaths = filePathsList(source); // Step 1: get all files from a directory
List<Path> filteredFilePaths = filter(filePaths); // Step 2: filter by ".txt"
Map<Path, List<String>> contentOfFiles = getContentOfFiles(filteredFilePaths); // Step 3: get content of files
move(filteredFilePaths, target); // Step 4: move files to destination
printToConsole(contentOfFiles); // Step 5: print content of files to console
}
public static List<Path> filePathsList(String directory) throws IOException {
List<Path> filePaths = new ArrayList<>();
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(FileSystems.getDefault().getPath(directory));
for (Path path : directoryStream) {
filePaths.add(path);
}
return filePaths;
}
private static List<Path> filter(List<Path> filePaths) {
List<Path> filteredFilePaths = new ArrayList<>();
for (Path filePath : filePaths) {
if (filePath.getFileName().toString().endsWith(".txt")) {
filteredFilePaths.add(filePath);
}
}
return filteredFilePaths;
}
private static Map<Path, List<String>> getContentOfFiles(List<Path> filePaths) throws IOException {
Map<Path, List<String>> contentOfFiles = new HashMap<>();
for (Path filePath : filePaths) {
contentOfFiles.put(filePath, new ArrayList<>());
Files.readAllLines(filePath).forEach(contentOfFiles.get(filePath)::add);
}
return contentOfFiles;
}
private static void move(List<Path> filePaths, String target) throws IOException {
Path targetDir = FileSystems.getDefault().getPath(target);
if (!Files.isDirectory(targetDir)) {
targetDir = Files.createDirectories(Paths.get(target));
}
for (Path filePath : filePaths) {
System.out.println("Moving " + filePath.getFileName() + " to " + targetDir.toAbsolutePath());
Files.move(filePath, Paths.get(target, filePath.getFileName().toString()), StandardCopyOption.ATOMIC_MOVE);
}
}
private static void printToConsole(Map<Path, List<String>> contentOfFiles) {
System.out.println("Content of files:");
contentOfFiles.forEach((k,v) -> v.forEach(System.out::println));
}
}

You could use File.lastModified() and sort it by its date.

Related

How to get file name having particular content in it using java?

Here I am trying to read a folder containing .sql files and I am getting those files in an array, now my requirement is to read every file and find particular word like as join if join is present in the file return filename or else discard , someone can pls help me with this ..
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public class Filter {
public static List<String> textFiles(String directory) {
List<String> textFiles = new ArrayList<String>();
File dir = new File(directory);
for (File file : dir.listFiles()) {
if (file.getName().endsWith((".sql"))) {
textFiles.add(file.getName());
}
}
return textFiles;
}
public static void getfilename(String directory) throws IOException {
List<String> textFiles = textFiles(directory);
for (String string : textFiles) {
Path path = Paths.get(string);
try (Stream<String> streamOfLines = Files.lines(path)) {
Optional<String> line = streamOfLines.filter(l -> l.contains("join")).findFirst();
if (line.isPresent()) {
System.out.println(path.getFileName());
} else
System.out.println("Not found");
} catch (Exception e) {
}
}
}
public static void main(String[] args) throws IOException {
getfilename("/home/niteshb/wave1-master/wave1/sql/scripts");
}
}
You can search word in file as belwo, pass the path of file
try(Stream <String> streamOfLines = Files.lines(path)) {
Optional <String> line = streamOfLines.filter(l ->
l.contains(searchTerm))
.findFirst();
if(line.isPresent()){
System.out.println(line.get()); // you can add return true or false
}else
System.out.println("Not found");
}catch(Exception e) {}
}
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public class Filter {
public static List<String> textFiles(String directory) {
List<String> textFiles = new ArrayList<String>();
File dir = new File(directory);
for (File file : dir.listFiles()) {
if (file.getName().endsWith((".sql"))) {
textFiles.add(file.getAbsolutePath());
}
}
System.out.println(textFiles.size());
return textFiles;
}
public static String getfilename(String directory) throws IOException {
List<String> textFiles = textFiles(directory);
for (String string : textFiles) {
Path path = Paths.get(string);
try (Stream<String> streamOfLines = Files.lines(path)) {
Optional<String> line = streamOfLines.filter(l -> l.contains("join")).findFirst();
if (line.isPresent()) {
System.out.println(path.getFileName());
} else
System.out.println("");
} catch (Exception e) {
}
}
return directory;
}
public static void main(String[] args) throws IOException {
getfilename("/home/wave1-master/wave1/sql/");
}
}

How to compare all file names from a given directory java?

I want to compare all file names from a given directory
Input/Output code:
static Scanner sc = new Scanner(System.in);
static String Directory = sc.next();
static File folder = new File(Directory);
static File[]listofFiles = folder.listFiles();
static String[] underFiles = folder.list();
public static void main(String[] args) throws IOException {
Main main = new Main();
main.walk(Directory);
}
public void walk( String path ) {
File root = new File( path );
File[] list = root.listFiles();
if (list == null) {
return;
}
for (File f : list) {
if ( f.isDirectory() ) {
walk( f.getAbsolutePath() );
System.out.println( "Dir:" + f.getAbsoluteFile() );
}
else {
System.out.println( "File:" + f.getName() );
}
}
}
The input is to give a directory path. The output will show all of the files in the given directory. How can I compare equal file names in this directory?
As I understand it, you want to locate directories that contain files with the same file name. For example, on a Windows machine, you may have several folders that contain image files. Usually each one of those folders will have a file named Thumbs.db. So you would like to know the names of the folders that contain a file named Thumbs.db.
The following code calls method walk of class java.nio.file.Files and manipulates the Stream returned by that method to create a Map where the Map key is the file name and the Map value is a List of all the folders that contain a file with that name.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class WalkTree {
public static void main(String[] args) {
Path path = Paths.get(args[0]);
try (Stream<Path> paths = Files.walk(path)) {
Map<Path, List<Path>> map = paths.filter(p -> Files.isRegularFile(p))
.collect(Collectors.toMap(p -> p.getFileName(),
p -> new ArrayList<Path>(List.of(p.getParent())),
(l1, l2) -> {l1.addAll(l2); return l1;}));
}
catch (IOException xIo) {
xIo.printStackTrace();
}
}
}
The first parameter to the toMap method, in the above code, is a Function that returns the Map key. The second parameter is another Function that returns the Map value. And the third parameter is a BinaryOperator that merges two different Map values that both have the same Map key.
Try this:
public static void main(String[] args) throws IOException {
String path = "/your/file-path/here";
try (Stream<Path> paths = Files.walk(Paths.get(path))) {
Map<String, List<Path>> map =
paths.filter(Files::isRegularFile)
.collect(groupingBy(p -> p.getFileName().toString()));
System.out.println(map);
}
}
Files.walk will walk all the hierarchy of files for you. The only thing you need to do is to consume the Paths from Stream.
If you still want to stick with your own code. Then you might do this instead:
public static void walk(String path, Map<String, List<String>> map) {
File root = new File(path);
File[] list = root.listFiles();
if (list == null) return;
for (File f : list) {
if (f.isDirectory()) {
walk(f.getAbsolutePath(), map);
System.out.println("Dir:" + f.getAbsoluteFile());
} else {
map.computeIfAbsent(f.getName(), k -> new ArrayList())
.add(f.getAbsolutePath());
System.out.println("File:" + f.getName());
}
}
}
and then:
public static void main(String[] args) {
String fileName = "/your/file-path/here";
Map<String, List<String>> map = new HashMap<>();
walk(fileName, map);
System.out.println(map);
}

Java copy files matching pattern from many folders to another folder

Please take a look at the code I have so far and if possible explain what I'm doing wrong. I'm trying to learn.
I made a little program to search for a type of file in a directory and all its sub-directories and copy them into another folder.
Code
import java.util.ArrayList;
import java.util.List;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
public class FandFandLoop {
public static void main(String[] args) {
final File folder = new File("C:/Users/ina/src");
List<String> result = new ArrayList<>();
search(".*\\.txt", folder, result);
File to = new File("C:/Users/ina/dest");
for (String s : result) {
System.out.println(s);
File from = new File(s);
try {
copyDir(from.toPath(), to.toPath());
System.out.println("done");
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void copyDir(Path src, Path dest) throws IOException {
Files.walk(src)
.forEach(source -> {
try {
Files.copy(source, dest.resolve(src.relativize(source)),
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
});
}
public static void search(final String pattern, final File folder, List<String> result) {
for (final File f : folder.listFiles()) {
if (f.isDirectory()) {
search(pattern, f, result);
}
if (f.isFile()) {
if (f.getName().matches(pattern)) {
result.add(f.getAbsolutePath());
}
}
}
}
}
It works, but what it actually does is to take my .txt files and write them into another file named dest without extension.
And at some point, it deletes the folder dest.
The deletion happens because of StandardCopyOption.REPLACE_EXISTING, if I understand this, but what I would have liked to obtain was that if several files had the same name then only one copy of it should be kept.
There is no need to call Files.walk on the matched source files.
You can improve this code by switching completely to using java.nio.file.Path and not mixing string paths and File objects. Additionally instead of calling File.listFiles() recursively you can use Files.walk or even better Files.find.
So you could instead use the following:
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Objects;
import java.util.function.BiPredicate;
import java.util.stream.Stream;
public class CopyFiles {
public static void copyFiles(Path src, Path dest, PathMatcher matcher, CopyOption... copyOptions) throws IOException {
// Argument validation
if (!Files.isDirectory(src)) {
throw new IllegalArgumentException("Source '" + src + "' is not a directory");
}
if (!Files.isDirectory(dest)) {
throw new IllegalArgumentException("Destination '" + dest + "' is not a directory");
}
Objects.requireNonNull(matcher);
Objects.requireNonNull(copyOptions);
BiPredicate<Path, BasicFileAttributes> filter = (path, attributes) -> attributes.isRegularFile() && matcher.matches(path);
// Use try-with-resources to close stream as soon as it is not longer needed
try (Stream<Path> files = Files.find(src, Integer.MAX_VALUE, filter)) {
files.forEach(file -> {
Path destFile = dest.resolve(src.relativize(file));
try {
copyFile(file, destFile, copyOptions);
}
// Stream methods do not allow checked exceptions, have to wrap it
catch (IOException ioException) {
throw new UncheckedIOException(ioException);
}
});
}
// Wrap UncheckedIOException; cannot unwrap it to get actual IOException
// because then information about the location where the exception was wrapped
// will get lost, see Files.find doc
catch (UncheckedIOException uncheckedIoException) {
throw new IOException(uncheckedIoException);
}
}
private static void copyFile(Path srcFile, Path destFile, CopyOption... copyOptions) throws IOException {
Path destParent = destFile.getParent();
// Parent might be null if dest is empty path
if (destParent != null) {
// Create parent directories before copying file
Files.createDirectories(destParent);
}
Files.copy(srcFile, destFile, copyOptions);
}
public static void main(String[] args) throws IOException {
Path srcDir = Paths.get("path/to/src");
Path destDir = Paths.get("path/to/dest");
// Could also use FileSystem.getPathMatcher
PathMatcher matcher = file -> file.getFileName().toString().endsWith(".txt");
copyFiles(srcDir, destDir, matcher);
}
}

Filtering only .txt files [duplicate]

Is there a built in Java code that will parse a given folder and search it for .txt files?
You can use the listFiles() method provided by the java.io.File class.
import java.io.File;
import java.io.FilenameFilter;
public class Filter {
public File[] finder( String dirName){
File dir = new File(dirName);
return dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename)
{ return filename.endsWith(".txt"); }
} );
}
}
Try:
List<String> textFiles(String directory) {
List<String> textFiles = new ArrayList<String>();
File dir = new File(directory);
for (File file : dir.listFiles()) {
if (file.getName().endsWith((".txt"))) {
textFiles.add(file.getName());
}
}
return textFiles;
}
You want to do a case insensitive search in which case:
if (file.getName().toLowerCase().endsWith((".txt"))) {
If you want to recursively search for through a directory tree for text files, you should be able to adapt the above as either a recursive function or an iterative function using a stack.
import org.apache.commons.io.filefilter.WildcardFileFilter;
.........
.........
File dir = new File(fileDir);
FileFilter fileFilter = new WildcardFileFilter("*.txt");
File[] files = dir.listFiles(fileFilter);
The code above works great for me
It's really useful, I used it with a slight change:
filename=directory.list(new FilenameFilter() {
public boolean accept(File dir, String filename) {
return filename.startsWith(ipro);
}
});
I made my solution based on the posts I found here with Google. And I thought there is no harm to post mine as well even if it is an old thread.
The only plus this code gives is that it can iterate through sub-directories as well.
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
Method is as follows:
List <File> exploreThis(String dirPath){
File topDir = new File(dirPath);
List<File> directories = new ArrayList<>();
directories.add(topDir);
List<File> textFiles = new ArrayList<>();
List<String> filterWildcards = new ArrayList<>();
filterWildcards.add("*.txt");
filterWildcards.add("*.doc");
FileFilter typeFilter = new WildcardFileFilter(filterWildcards);
while (directories.isEmpty() == false)
{
List<File> subDirectories = new ArrayList();
for(File f : directories)
{
subDirectories.addAll(Arrays.asList(f.listFiles((FileFilter)DirectoryFileFilter.INSTANCE)));
textFiles.addAll(Arrays.asList(f.listFiles(typeFilter)));
}
directories.clear();
directories.addAll(subDirectories);
}
return textFiles;
}
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
public class FileFinder extends SimpleFileVisitor<Path> {
private PathMatcher matcher;
public ArrayList<Path> foundPaths = new ArrayList<>();
public FileFinder(String pattern) {
matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
}
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path name = file.getFileName();
if (matcher.matches(name)) {
foundPaths.add(file);
}
return FileVisitResult.CONTINUE;
}
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws IOException {
Path fileDir = Paths.get("files");
FileFinder finder = new FileFinder("*.txt");
Files.walkFileTree(fileDir, finder);
ArrayList<Path> foundFiles = finder.foundPaths;
if (foundFiles.size() > 0) {
for (Path path : foundFiles) {
System.out.println(path.toRealPath(LinkOption.NOFOLLOW_LINKS));
}
} else {
System.out.println("No files were founds!");
}
}
}
import org.apache.commons.io.FileUtils;
List<File> htmFileList = new ArrayList<File>();
for (File file : (List<File>) FileUtils.listFiles(new File(srcDir), new String[]{"txt", "TXT"}, true)) {
htmFileList.add(file);
}
This is my latest code to add all text files from a directory
Here is my platform specific code(unix)
public static List<File> findFiles(String dir, String... names)
{
LinkedList<String> command = new LinkedList<String>();
command.add("/usr/bin/find");
command.add(dir);
List<File> result = new LinkedList<File>();
if (names.length > 1)
{
List<String> newNames = new LinkedList<String>(Arrays.asList(names));
String first = newNames.remove(0);
command.add("-name");
command.add(first);
for (String newName : newNames)
{
command.add("-or");
command.add("-name");
command.add(newName);
}
}
else if (names.length > 0)
{
command.add("-name");
command.add(names[0]);
}
try
{
ProcessBuilder pb = new ProcessBuilder(command);
Process p = pb.start();
p.waitFor();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
{
// System.err.println(line);
result.add(new File(line));
}
p.destroy();
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}

How to get absolute paths of files in a directory?

I have a directory with files, directories, subdirectories, etc. How I can get the list of absolute paths to all files and directories using the Apache Hadoop API?
Using HDFS API :
package org.myorg.hdfsdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class HdfsDemo {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
conf.addResource(new Path("/Users/miqbal1/hadoop-eco/hadoop-1.1.2/conf/core-site.xml"));
conf.addResource(new Path("/Users/miqbal1/hadoop-eco/hadoop-1.1.2/conf/hdfs-site.xml"));
FileSystem fs = FileSystem.get(conf);
System.out.println("Enter the directory name :");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Path path = new Path(br.readLine());
displayDirectoryContents(fs, path);
}
private static void displayDirectoryContents(FileSystem fs, Path rootDir) {
// TODO Auto-generated method stub
try {
FileStatus[] status = fs.listStatus(rootDir);
for (FileStatus file : status) {
if (file.isDir()) {
System.out.println("This is a directory:" + file.getPath());
displayDirectoryContents(fs, file.getPath());
} else {
System.out.println("This is a file:" + file.getPath());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Writer a recursive function which takes a file and check if its a directory or not, if directory list out all files in it and in a for loop check if the file is a directory then recursively call or just return the list of files.
Something like this below but not exactly same (here I am returning only .java files)
private static List<File> recursiveDir(File file) {
if (!file.isDirectory()) {
// System.out.println("[" + file.getName() + "] is not a valid directory");
return null;
}
List<File> returnList = new ArrayList<File>();
File[] files = file.listFiles();
for (File f : files) {
if (!f.isDirectory()) {
if (f.getName().endsWith("java")) {
returnList.add(f);
}
} else {
returnList.addAll(recursiveDir(f));
}
}
return returnList;
}
with hdfs you can use hadoop fs -lsr .

Categories

Resources