I want to compare file lying in two different folders.
I wish to compare only files which have same name in those two different folders.
What I wish to do is to compare two different versions of a software and find how many files have been changed.
This will help you get files for two paths:
import java.io.File;
import java.util.*;
public class ListFiles
{
public static void main(String[] args)
{
// First directory path here.
String path1 = ".";
// Second directory path here.
String path2 = ".";
// File class is very important.
// If you did a simple Google search
// Then you would have seen this class mentioned.
File folder1 = new File(path1);
File folder2 = new File(path2);
// It gets the list of files for you.
File[] listOfFiles1 = folder1.listFiles();
File[] listOfFiles2 = folder2.listFiles();
// We'll need these to store the file names as Strings.
ArrayList<String> fileNames1 = new ArrayList<String>();
ArrayList<String> fileNames2 = new ArrayList<String>();
// Get file names from first directory.
for (int i = 0; i < listOfFiles1.length; i++)
{
if (listOfFiles1[i].isFile())
{
fileNames1.add(listOfFiles1[i].getName());
}
}
// Get file names from second directory.
for (int i = 0; i < listOfFiles2.length; i++)
{
if (listOfFiles2[i].isFile())
{
fileNames2.add(listOfFiles2[i].getName());
}
}
// Now compare
// Loop through the two array lists and add your own logic.
}
}
You will need to add your own logic to compare. Source
I have this code which compares all the files in the directory with a particular file to check if that files aleady exists in the directory,may tweak that a little as per your needs.It uses commons-io.jar
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
public class CompareFile {
String directory;
File file;
public CompareFile(String directory, File file) {
this.directory = directory;
this.file = file;
}
public boolean doesFileExist() {
boolean indicatorFileExist = true;
List<File> files = null;
try {
files = getFiles();
files = files.stream().filter(fileMatch -> {
try {
if(fileMatch.isFile()){
return FileUtils.contentEquals(fileMatch, file);
}else{
return false;
}
} catch (Exception excep) {
excep.printStackTrace();
return false;
}
}).collect(Collectors.toList());
if(files.isEmpty()){
indicatorFileExist = false;
}
} catch (Exception excep) {
excep.printStackTrace();
} finally {
if (files != null) {
files = null;
}
}
return indicatorFileExist;
}
private List<File> getFiles() {
List<File> fileList = null;
try {
if(directory!=null && directory.trim().length()>0 && file!=null){
File dir = new File(directory);
if(dir.isDirectory() && dir.exists() && dir.canRead()){
fileList = Arrays.asList(dir.listFiles());
}
}
} catch (Exception excep) {
excep.printStackTrace();
}
return fileList;
}
}
Related
I have a problem, i have this directory with 1k+ files and some folders. I need find the path of the files(which are in subdirectories) that starts with "BCM", but not only the first i find but every single file which start with that.
I tried looking at other answers about this topic but i couldn't find help,
tried using this code:
File dir = new File("K:\\Jgencs");
FilenameFilter filter = new FilenameFilter()
{
public boolean accept (File dir, String name)
{
return name.startsWith("BCM");
}
};
String[] children = dir.list(filter);
if (children == null)
{
System.out.println("No directory found");
}
else
{
for (int i = 0; i< children.length; i++)
{
String filename = children[i];
System.out.println(filename);
File h = new File(dir,filename);
System.out.println(h.getAbsolutePath()
[UPDATED] This is how you can achieve using plain Java and filter text from a variable passing as parameter:
Here is my directory: /tmp
And here is the code running:
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class GetAllFilesInDirectory {
public static void main(String[] args) throws IOException {
String filter = "BCM";
List<File> files = listFiles("/tmp", new CustomerFileFilter(filter));
for (File file : files) {
System.out.println("file: " + file.getCanonicalPath());
}
}
private static List<File> listFiles(String directoryName, CustomerFileFilter fileFilter) {
File directory = new File(directoryName);
List<File> files = new ArrayList<>();
// Get all files from a directory.
File[] fList = directory.listFiles(fileFilter);
if(fList != null) {
for (File file : fList) {
if (file.isFile()) {
files.add(file);
} else if (file.isDirectory()) {
files.addAll(listFiles(file.getAbsolutePath(), fileFilter));
}
}
}
return files;
}
}
class CustomerFileFilter implements FileFilter {
private final String filterStartingWith;
public CustomerFileFilter(String filterStartingWith) {
this.filterStartingWith = filterStartingWith;
}
#Override
public boolean accept(File file) {
return file.isDirectory() || file.isFile() && file.getName().startsWith(filterStartingWith);
}
}
This is the output:
file: /private/tmp/BCM01.txt
file: /private/tmp/BCM01
file: /private/tmp/subfolder1/BCM02.txt
Doing recursive calls to the method when finding a directory to also list the files form inside, and filtering by name the files before adding.
You want Files.walk:
try (Stream<Path> files = Files.walk(Paths.get("K:\\Jgencs"))) {
files.filter(f -> f.getFileName().toString().startsWith("BCM")).forEach(
file -> System.out.println(file));
}
This question already has answers here:
Standard concise way to copy a file in Java?
(16 answers)
Closed 6 years ago.
I am trying to write a java program that will take two arguments, dirName and fileName. The program will search for all the files in dirName that end with .java and then concatenate them into a new folder called fileName. So far I have a method to search for .java files in dirName, I then put them in a file array called list but now I am struggling to iteratively add the files in this array to my new folder, fileName. Here is what I have so far:
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.util.ArrayList;
public class TwoFiles {
File dir;
File name;
public TwoFiles(File dirName, File fileName) {
dir = dirName;
name = fileName;
}
public void setDir(File m) {
this.dir = m;
}
public File getDir() {
return dir;
}
public void setNewFolder(File n) {
this.name = n;
}
public File getNewFolder() {
return name;
}
public File[] Finder(File dir) {
dir = getDir();
return dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename) {
return name.endsWith(".java"); }
} );
}
public static void main(String[] args) {
File folder = null;
File newFolder = null;
Integer b = null;
TwoFiles tf = new TwoFiles(folder, newFolder);
folder = tf.getDir();
newFolder = tf.getNewFolder();
File[] list = tf.Finder(folder); //add to an array
//here is where I've been experimenting to add files in `list` to new folder, `fileName`.
for (File file : list)
{
FileInputStream inFile = new FileInputStream(file);
while ((b = inFile.read()) != -1)
newFolder.write(b);
inFile.close();
}
//copy files from array (list) into newFolder
}
}
Thanks for your time.
Your newFolder variable is of type File. You cannot write into this. I assume, your code does not even compile. You have to create an output stream in front of your loop:
FileOutputStream fos = new FileOutputStream( newFolder);
try
{
for (File file : list)
{
FileInputStream inFile = new FileInputStream(file);
while ((b = inFile.read()) != -1)
fos.write(b);
inFile.close();
}
}
finally
{
fos.close();
}
You can use the Apache Commons IO copyDirectory() with the IOFileFilter (for .java extensions) to copy your files from one directory to another. Before that you can ensure to create a new directory using forceMkdir() for your filename.
It's my version of your problem:
I created other constructor, where you can put only paths to directory/folder from you want concatenate files, and to file of concatenations result.
public class TwoFiles {
private File dir;
private File name;
public TwoFiles(File dirName, File fileName) {
dir = dirName;
name = fileName;
}
public TwoFiles(String dirName, String destinationFileName) throws IOException{
dir=new File(dirName);
if(!dir.isDirectory()){
throw new FileNotFoundException();//here your exception in case when dirName is file name instead folder name
}
name=new File(destinationFileName);
if(!name.exists()){
name.createNewFile();
}
}
public void setDir(File m) {
this.dir = m;
}
public File getDir() {
return dir;
}
public void setNewFolder(File n) {
this.name = n;
}
public File getNewFolder() {
return name;
}
public void concatenateFiles() throws IOException{
File[] files=dir.listFiles();
for(File file: files){
if(file.getName().endsWith(".java")){ //check is right file
prescribe(name, file);
}
}
}
/** prescribe file to new destination */
private void prescribe(File destination, File file) throws IOException {
FileInputStream inFile = new FileInputStream(file);
FileOutputStream writer=new FileOutputStream(destination, true); //true means next file will be write beginning from end of the file
int x;
while((x=inFile.read())!=-1){
writer.write(x);
}
String test="\n"; //next line in file
writer.write(test.getBytes());
writer.close();
inFile.close();
}
public static void main(String...strings){
String dirName="C/myApp/model/entity";
String fileName="C:/Users/Dell/Desktop/temp/test.java";
try {
new TwoFiles(dirName, fileName).concatenateFiles();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I want include copyright comment on the top of every java file. I want to do it via eclipse formatter.
If it is not possible, please suggest any other way to include the copyright in existing java file.
Although it may not perfectly suit the intended approach (that is, using an eclipse plugin for that) : Once I created a small utility class that does exactly this.
It collects a list of all .java files in a given source directory. For each of the resulting files, it looks for the first line starting with the word "package". If the part above this line is not empty, then it will assume that a header is already present, and skip this file. Otherwise, it will insert a header (which is contained in some template file) before the line starting with "package".
This could arbitrarily be improved and generalized, but I only once wrote it down in order to quickly insert copyright headers into the files of an existing code base, and it worked well. Maybe you (or others) find it helpful.
import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class HeaderInserter
{
public static void main(String[] args)
{
String headerTemplateFileName = "HeaderTemplate.txt";
String path = "C:/Workspace/HeaderInserter/src";
insertHeaders(path, headerTemplateFileName);
}
private static void insertHeaders(String path, String headerTemplateFileName)
{
FilenameFilter filenameFilter = new FilenameFilter()
{
#Override
public boolean accept(File dir, String name)
{
return name.toLowerCase().endsWith(".java");
}
};
List<String> headerLines = readLines(headerTemplateFileName);
List<File> files = listFiles(new File(path), filenameFilter);
for (File file : files)
{
System.out.println("Inserting header into "+file);
handle(file, headerLines);
}
System.out.println("Done");
}
private static void handle(File inputFile, List<String> headerLines)
{
List<String> lines = readLines(inputFile.getPath());
int index = lineIndexStartingWith(lines, "package");
if (index == -1)
{
System.err.println("No 'package' line found in "+inputFile);
return;
}
if (index > 0)
{
List<String> removedLines = lines.subList(0, index);
String removedPart = createString(removedLines);
String removedContents = removedPart.replaceAll("\n", "");
if (removedContents.trim().length() > 0)
{
System.err.println("Non-empty header found in "+inputFile);
System.err.println(removedPart);
System.err.println("Skipping");
return;
}
}
List<String> keptLines = lines.subList(index, lines.size());
List<String> writtenLines = new ArrayList<String>();
writtenLines.addAll(headerLines);
writtenLines.addAll(keptLines);
String writtenContent = createString(writtenLines);
File outputFile = new File(inputFile.getName()+"_header");
boolean written = writeContent(outputFile, writtenContent);
if (written)
{
boolean deleted = inputFile.delete();
if (!deleted)
{
System.err.println(
"Could not delete old input file: "+inputFile);
return;
}
boolean renamed = outputFile.renameTo(inputFile);
if (!renamed)
{
System.err.println("Could not rename "+outputFile);
System.err.println(" to "+inputFile);
return;
}
System.out.println("Inserted header into "+inputFile);
}
}
private static int lineIndexStartingWith(
List<String> lines, String prefix)
{
for (int i=0; i<lines.size(); i++)
{
String line = lines.get(i);
if (line.trim().startsWith(prefix))
{
return i;
}
}
return -1;
}
private static String createString(List<String> lines)
{
StringBuilder sb = new StringBuilder();
for (String line : lines)
{
sb.append(line).append("\n");
}
return sb.toString();
}
private static boolean writeContent(
File outputFile, String writtenContent)
{
try (FileWriter fw = new FileWriter(outputFile))
{
fw.write(writtenContent);
fw.close();
return true;
}
catch (IOException e)
{
e.printStackTrace();
}
return false;
}
private static List<String> readLines(String fileName)
{
try
{
return Files.readAllLines(
Paths.get(fileName), Charset.defaultCharset());
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
}
private static List<File> listFiles(
File rootDirectory, FilenameFilter filenameFilter)
{
List<File> result = new ArrayList<File>();
listFiles(rootDirectory, filenameFilter, result);
return result;
}
private static void listFiles(
File file, FilenameFilter filenameFilter, List<File> result)
{
if (!file.isDirectory())
{
if (filenameFilter.accept(file.getParentFile(), file.getName()))
{
result.add(file);
}
}
else
{
File files[] = file.listFiles();
for (File f : files)
{
listFiles(f, filenameFilter, result);
}
}
}
}
Try Eclipse Releng Tools here
Write a script to update each file and add first line - use eclipse find and replace regex
http://java.dzone.com/articles/using-regular-expressions
I am trying to list all directories and files within a certain directory, but while "D:\data" works, "D:\" doesn't. "D" is a secondary disk.
This is the exception:
Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Arrays$ArrayList.<init>(Arrays.java:3813)
at java.util.Arrays.asList(Arrays.java:3800)
at project.1.scavenger.listf(scavenger.java:19)
at project.1.scavenger.listf(scavenger.java:30)
at project.1.scavenger.listf(scavenger.java:30)
at project.1.main(Project1.java:28)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
Code:
public static List<File> listf(String directoryName) throws IOException {
File directory = new File(directoryName);
List<File> resultList = new ArrayList<File>();
// get all the files from a directory
File[] fList = directory.listFiles();
resultList.addAll(Arrays.asList(fList));
for (File file : fList) {
if (file.isFile()) {
System.out.println(file.getAbsolutePath());
try {
System.out.println(scavenger.checkmime(file.getAbsolutePath()));
} catch (Exception ex) {
}
} else if (file.isDirectory()) {
resultList.addAll(listf(file.getAbsolutePath()));
}
}
// System.out.println(fList);
return resultList;
}
public static String checkmime(String fl) throws MalformedURLException, IOException {
File file = new File(fl);
String mimeType = file.toURL().openConnection().getContentType();
// System.out.println(mimeType);
return mimeType;
}
What's wrong with my code?
Removed error from your version
In your recursion you never ask for null values. Do it and it should run like this:
public static List<File> listf(String directoryName) throws IOException {
File directory = new File(directoryName);
List<File> resultList = new ArrayList<>();
// get all the files from a directory
File[] fList = directory.listFiles();
// this was missing
if (fList == null) {
return null;
}
resultList.addAll(Arrays.asList(fList));
for (File file : fList) {
if (file.isFile()) {
System.out.println(file.getAbsolutePath());
try {
System.out.println(checkmime(file.getAbsolutePath()));
} catch (Exception ex) {
}
} else if (file.isDirectory()) {
// ask here if it was null
List<File> files = listf(file.getAbsolutePath());
if (files != null) {
resultList.addAll(files);
}
}
}
//System.out.println(fList);
return resultList;
}
Why D:\data works and D:\ not
In every root of a drive in a Windows System is a hidden folder structure called $RECYCLE.BIN. In this folder windows stores for each user (sid) an own folder with deleted data (links to it). But a normal user is only allowed to get the first level and not the user folder (with sid value as name).
(German Windows: Papierkorb = Trash)
A maybe much better solution:
A maybe better way of doing such searchings in tree's is to create an Iterator over the directory tree (like a composite iterator). This solution also uses only Java NIO features, so the platform should be changeable (haven't tested!) to for ex. Linux.
DirectoryTreeIterator.java
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
public class DirectoryTreeIterator implements Iterator<Path> {
private final Deque<Iterator<Path>> deque = new ArrayDeque<>();
public DirectoryTreeIterator(Iterator<Path> it) {
deque.push(it);
}
#Override
public boolean hasNext() {
if (deque.isEmpty()) {
return false;
} else {
Iterator<Path> it = deque.peek();
if (!it.hasNext()) {
deque.pop();
return hasNext();
} else {
return true;
}
}
}
#Override
public Path next() {
if (hasNext()) {
Iterator<Path> it = deque.peek();
Path p = it.next();
try {
// here is the magic recursive on only filtered paths
if (Files.isDirectory(p) && Files.isReadable(p) && !Files.isHidden(p)) {
deque.push(Files.newDirectoryStream(p).iterator());
}
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return p;
} else {
return null;
}
}
}
Then you are able to use it like a charm:
FileLister.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
public class FileLister {
public static void main(String[] args) throws IOException {
Path p = Paths.get("D:\\");
Iterator<Path> it = Files.newDirectoryStream(p).iterator();
DirectoryTreeIterator dti = new DirectoryTreeIterator(it);
while (dti.hasNext()) {
Path path = dti.next();
if (!Files.isDirectory(path)) {
String mime = Files.probeContentType(path);
System.out.println("Mime of File "
+ path.getFileName() + " is: " + mime);
}
}
}
}
If you add this code right beneath the directory.listFiles() call:
if (fList == null) {
System.out.println("Couldn't read files in directory: " + directoryName);
return resultList;
}
then you will get a message like this:
Couldn't read files in directory: G:\$RECYCLE.BIN\Windows SID
This Windows SIDs is security identifier for a user on your local machine.
So that means your current user has no permission to read this directory (it belongs to a different user) in the "recycle bin" directory, therefore listFiles() returns null instead of a String[].
You could keep the check and the message I've posted, or you can implement a different way to handle "unreadable" directories.
About why "D:\\" failed and "D:\\data" not:
"D:\\" contains the mentioned "$RECYCLE.BIN" directory with restricted access
"D:\\data" has no directory where your current user isn't allowed to access/read it, therefore listFiles() never returned null.
What i wanna do is to recursively search for some files on the external sd-card. The problem is that the code is looking ok, but (assuming .txt files) it only shows me 7 files out of 100+ that are being spread throughout folders.
The code is this:
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
void makelist(File file){
if(file.isFile()){
if(SimpleAdapter.getFileType(file)==null)
mis.add(file);
else if(SimpleAdapter.getFileType(file).equalsIgnoreCase("text"))
doc.add(file);
}else if(file.isDirectory()){
for(File f:file.listFiles())
makelist(f);
}
}
Any idea how could i make it run correctly?
Assuming you are building two lists (misc files and doc files), try with below code which all all files other than text files to misc and text files to doc.
if(SimpleAdapter.getFileType(file) == null || !SimpleAdapter.getFileType(file).equalsIgnoreCase("text"))
mis.add(file);
else
doc.add(file);
Not sure why it is not working for you. Tried a test program and it worked perfectly...
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class FileChecker
{
/**
* #param args
*/
public static void main(String[] args) {
SimpleAdapterTest adapter = new SimpleAdapterTest();
adapter.makelist(new File("C:\\MYFolder"));
adapter.showList();
}
}
class SimpleAdapterTest
{
List<File> mis = new ArrayList<File>();
List<File> doc = new ArrayList<File>();
public static String getFileType(File f)
{
String Name = f.getName();
if (f.getName().endsWith(".txt") || Name.endsWith(".TXT")
|| Name.endsWith(".inf") || Name.endsWith(".INF"))
return "text";
return null;
}
public void makelist(File file){
if(file.isFile()){
if(SimpleAdapterTest.getFileType(file)==null)
mis.add(file);
else if(SimpleAdapterTest.getFileType(file).equalsIgnoreCase("text"))
doc.add(file);
}else if(file.isDirectory()){
for(File f:file.listFiles())
makelist(f);
}
}
public void showList()
{
for(File miscFile : mis)
{
System.out.println("Misc files = " + miscFile.getName());
}
for(File docfile : doc)
{
System.out.println("Doc files = " + docfile.getName());
}
}
}