Java - traverse through folders and do something if intended folder is present - java

Being very new to Java, I'm unable to bring a small concept to a syntactic form. Apologies.
My project structure looks like below & i'm trying to walk thru the sub folders of applications
directory & search for a folder named conduit, if present, create a new folder called base parallel to it.
At best I came up with the below code, post that, kind of struggling.
/home/project_A/applications
|sub_project_A
|target
|conduit
|sub_project_B
|target
|conduit
|sub_project_C
|target
|class
|sub_project_D
|target
|conduit
public class Test
{
public static void main(String[] args)
{
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
String appDir = s + "/applications";
System.out.println("Directory Exists" + appDir);
}
}

You can use BFS to traverse the sub directories:
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.Queue;
public class MyClass {
public static void main(String[] args) {
Path currentRelativePath = Paths.get("");
Queue<Path> paths = new LinkedList<>();
paths.add(currentRelativePath);
while(!paths.isEmpty()) {
Path current = paths.poll();
File currentFile = current.toFile();
if(currentFile.isDirectory()) {
if(currentFile.getName().equals("conduit")) {
// Found the directory called conduit, Do what you have to do here
}else {
for(String fileName : currentFile.list()) {
paths.add(Paths.get(currentFile.getAbsolutePath()+"/"+fileName));
}
}
}
}
}
}

Using Files.find is a good way to traverse a series of directories quickly to find files or directories matching any criteria you need. Here is an example which prints off the matches:
BiPredicate<Path, BasicFileAttributes> predicate = (p,a) -> a.isDirectory() && "conduit".equals(p.getFileName().toString());
try(var dirs = Files.find(Path.of("."), Integer.MAX_VALUE, predicate)) {
dirs.forEach(p -> {
System.out.println("Found "+p+", create if not exists: "+p.resolveSibling("base"));
}
);
}

Related

Moving large files in java

I have to move files from one directory to other directory.
Am using property file. So the source and destination path is stored in property file.
Am haivng property reader class also.
In my source directory am having lots of files. One file should move to other directory if its complete the operation.
File size is more than 500MB.
import java.io.File;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import static java.nio.file.StandardCopyOption.*;
public class Main1
{
public static String primarydir="";
public static String secondarydir="";
public static void main(String[] argv)
throws Exception
{
primarydir=PropertyReader.getProperty("primarydir");
System.out.println(primarydir);
secondarydir=PropertyReader.getProperty("secondarydir");
File dir = new File(primarydir);
secondarydir=PropertyReader.getProperty("secondarydir");
String[] children = dir.list();
if (children == null)
{
System.out.println("does not exist or is not a directory");
}
else
{
for (int i = 0; i < children.length; i++)
{
String filename = children[i];
System.out.println(filename);
try
{
File oldFile = new File(primarydir,children[i]);
System.out.println( "Before Moving"+oldFile.getName());
if (oldFile.renameTo(new File(secondarydir+oldFile.getName())))
{
System.out.println("The file was moved successfully to the new folder");
}
else
{
System.out.println("The File was not moved.");
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
System.out.println("ok");
}
}
}
My code is not moving the file into the correct path.
This is my property file
primarydir=C:/Desktop/A
secondarydir=D:/B
enter code here
Files should be in B drive. How to do? Any one can help me..!!
Change this:
oldFile.renameTo(new File(secondarydir+oldFile.getName()))
To this:
oldFile.renameTo(new File(secondarydir, oldFile.getName()))
It's best not to use string concatenation to join path segments, as the proper way to do it may be platform-dependent.
Edit: If you can use JDK 1.7 APIs, you can use Files.move() instead of File.renameTo()
Code - a java method:
/**
* copy by transfer, use this for cross partition copy,
* #param sFile source file,
* #param tFile target file,
* #throws IOException
*/
public static void copyByTransfer(File sFile, File tFile) throws IOException {
FileInputStream fInput = new FileInputStream(sFile);
FileOutputStream fOutput = new FileOutputStream(tFile);
FileChannel fReadChannel = fInput.getChannel();
FileChannel fWriteChannel = fOutput.getChannel();
fReadChannel.transferTo(0, fReadChannel.size(), fWriteChannel);
fReadChannel.close();
fWriteChannel.close();
fInput.close();
fOutput.close();
}
The method use nio, it make use os underling operation to improve performance.
Here is the import code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
If you are in eclipse, just use ctrl + shift + o.

Get all classes from a Jar file using Reflection

I need to get all the Classes from a Jar file that's on the ClassPath and I used this article for my solution. The methods from the article work when I set the path to a package name but does not work if the package is in a Jar file.
Under the comments people posted code which they claim will work for Jar files (they modified the articles code). I've looked over their code and it seems like it should work, and it does work for packages that are not in jar files, but they did not specify what to pass in as the argument telling the methods the package is from a jar file. I've tried every combination I could think of but nothing will work.
So, with a package that's not in a Jar file, this would be the working way to use the methods,
Class[] myClasses = getClassesInPackage("my.package.name", null);
And it's supposed to work with a package in a Jar file but I don't know what to replace "my.package.name" with. I've tried just giving the package name that's on the Jar file but it doesn't find anything.
My idea is it's something similar to "myJarName" or "myJarName.my.package.name" but none of these are working.
Here is the full code,
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Member;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.TreeSet;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static java.lang.System.out;
public class ClassSpy {
public static void main(String... args) {
try {
Class[] myClasses = getClassesInPackage("you.package.name.here", null);
for(Class index: myClasses)
out.format("Class:%n %s%n%n", index.getCanonicalName());
}
catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
/**
* Scans all classes accessible from the context
* class loader which belong to the given package
* and subpackages. Adapted from
* http://snippets.dzone.com/posts/show/4831
* and extended to support use of JAR files
* #param packageName The base package
* #param regexFilter an optional class name pattern.
* #return The classes
*/
public static Class[] getClassesInPackage(String packageName, String regexFilter) {
Pattern regex = null;
if (regexFilter != null)
regex = Pattern.compile(regexFilter);
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<String> dirs = new ArrayList<String>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(resource.getFile());
}
TreeSet<String> classes = new TreeSet<String>();
for (String directory : dirs) {
classes.addAll(findClasses(directory, packageName, regex));
}
ArrayList classList = new ArrayList();
for (String clazz : classes) {
classList.add(Class.forName(clazz));
}
return (Class[]) classList.toArray(new Class[classes.size()]);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Recursive method used to find all classes in a given path
* (directory or zip file url). Directories are searched recursively.
* (zip files are Adapted from http://snippets.dzone.com/posts/show/4831
* and extended to support use of JAR files #param path The base
* directory or url from which to search. #param packageName The package
* name for classes found inside the base directory #param regex an
* optional class name pattern. e.g. .*Test*
* #return The classes
*/
private static TreeSet findClasses(String path, String packageName, Pattern regex) throws Exception {
TreeSet classes = new TreeSet();
if (path.startsWith("file:") && path.contains("!")) {
String[] split = path.split("!");
URL jar = new URL(split[0]);
ZipInputStream zip = new ZipInputStream(jar.openStream());
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
System.out.println("Here 1");
if (entry.getName().endsWith(".class")) {
System.out.println("Here 2");
String className = entry.getName()
.replaceAll("[$].*", "")
.replaceAll("[.]class", "")
.replace('/', '.');
if (className.startsWith(packageName) && (regex == null
|| regex.matcher(className).matches()))
classes.add(className);
}
}
}
File dir = new File(path);
if (!dir.exists()) {
return classes;
}
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file.getAbsolutePath()
, packageName + "." + file.getName()
, regex));
}
else if (file.getName().endsWith(".class")) {
String className = packageName + '.' + file
.getName()
.substring(0, file.getName().length() - 6);
if (regex == null || regex.matcher(className).matches())
classes.add(className);
}
}
return classes;
}
}
You should be able to copy all of the code and compile it (some imports won't be used because I'm only showing the parts related to the problem and not the whole program).
For a working demonstration you can change "my.package.name" to some package you have that's on the classpath.
Class[] myClasses = getClassesInPackage("my.package.name", null);
Ive never used this method before if i would need to do what you're trying to do i would just use
Classname name = new Classname();

File Not Found Exception - Can't see the issue

I've tried directly linking using the entire path but that hasn't solved it either.
package eliza;
import java.io.*;
public class Eliza {
public static void main(String[] args) throws IOException {
String inputDatabase = "src/eliza/inputDataBase.txt";
String outputDatabase = "src/eliza/outputDataBase.txt";
Reader database = new Reader();
String[][] inputDB = database.Reader(inputDatabase);
String[][] outputDB = database.Reader(outputDatabase);
}
}
Here is the reader class:
package eliza;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Reader {
public String[][] Reader(String name) throws IOException {
int length = 0;
String sizeLine;
FileReader sizeReader = new FileReader(name);
BufferedReader sizeBuffer = new BufferedReader(sizeReader);
while((sizeLine = sizeBuffer.readLine()) != null) {
length++;
}
String[][] database = new String[length][1];
return (database);
}
}
Here's a photo of my directory. I even put these text files in the "eliza" root folder: here
Any ideas?
Since you are using an IDE, you need to give the complete canonical path. It should be
String inputDatabase = "C:\\Users\\Tommy\\Desktop\\Eliza\\src\\eliza\\inputDataBase.txt";
String outputDatabase = "C:\\Users\\Tommy\\Desktop\\Eliza\\src\\eliza\\outputDataBase.txt";
The IDE is probably executing the bytecode from its bin folder and cannot find the relative reference.
give the exact path like
String inputDatabase = "c:/java/src/eliza/inputDataBase.txt";
you have not given the correct path, Please re check
try
{BASE_PATH}+ "Eliza/src/inputDataBase.txt"
The source directory tree isn't generally present during execution, so files that are required at runtime shouldn't be put there ... unless you're going to use them as resources, in which case their pathname is relative to the package root, and does not begin with 'src', and the data is accessed by a getResourceXXX() method, not via a FileInputStream.

Eclipse shows errors when i write information in xml file

I use the JDOM library. When I write information into an xml file, Eclipse shows errors. The system cannot find the path specified. I try to create the file in the "language" folder. How can I create the folder automatically when I write info into this file? I think the error is in this line:
FileWriter writer = new FileWriter("language/variants.xml");
Here is my code:
package test;
import java.io.FileWriter;
import java.util.LinkedList;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
class Test {
private LinkedList<String> variants = new LinkedList<String>();
public Test() {
}
public void write() {
Element variantsElement = new Element("variants");
Document myDocument = new Document(variantsElement);
int counter = variants.size();
for(int i = 0;i < counter;i++) {
Element variant = new Element("variant");
variant.setAttribute(new Attribute("name",variants.pop()));
variantsElement.addContent(variant);
}
try {
FileWriter writer = new FileWriter("language/variants.xml");
XMLOutputter outputter = new XMLOutputter();
outputter.setFormat(Format.getPrettyFormat());
outputter.output(myDocument,writer);
writer.close();
}
catch(java.io.IOException exception) {
exception.printStackTrace();
}
}
public LinkedList<String> getVariants() {
return variants;
}
}
public class MyApp {
public static void main(String[] args) {
Test choice = new Test();
choice.write();
}
}
Here is the error:
java.io.FileNotFoundException: language\variants.xml (The system cannot find the path specified)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
at java.io.FileOutputStream.<init>(FileOutputStream.java:104)
at java.io.FileWriter.<init>(FileWriter.java:63)
at test.Test.write(MyApp.java:31)
at test.MyApp.main(MyApp.java:49)`enter code here
As the name suggests FileWriter is for writing to file. You need to create the directory first if it doesnt already exist:
File theDir = new File("language");
if (!theDir.exists()) {
boolean result = theDir.mkdir();
// Use result...
}
FileWriter writer = ...
For creating directories you need to use mkdir() of File class.
Example:
File f = new File("/home/user/newFolder");
f.mkdir();
It returns a boolean: true if directory created and false if it failed.
mkdir() also throws Security Exception if security manager exists and it's checkWrite() method doesn't allow the named directory to be created.
PS: Before creating directory, you need to validate if this directory already exists or not by using exists() which also returns boolean.
Regards...
Mr.777

Creating a directory wherever jar file is located through java

I have already surveyed SO for an answer, and could not find an appropriate one.
When I launch my program from a jar I need to create a folder in the directory where the jar file is located. It should not matter where the user saves the jar file.
Here is the newest code I was playing with: A System.out.println will print out the correct directory but the folder will not be created. In contrast,everything is being saved to my System32 folder as of now.
public static String getProgramPath() throws IOException{
String currentdir = System.getProperty("user.dir");
currentdir = currentdir.replace( "\\", "/" );
return currentdir;
}
File dir = new File(getProgramPath() + "Comics/");//The name of the directory to create
dir.mkdir();//Creates the directory
To get a Jar's path can be a little trickier than simply getting the user.dir directory. I can't remember the details why, but user.dir does not return this path reliably in all situations. If you absolutely must get the jar's path, then you need to do a little black magic and first get the class's protectionDomain. Something like:
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import javax.swing.JOptionPane;
public class MkDirForMe {
public static void main(String[] args) {
try {
String path = getProgramPath2();
String fileSeparator = System.getProperty("file.separator");
String newDir = path + fileSeparator + "newDir2" + fileSeparator;
JOptionPane.showMessageDialog(null, newDir);
File file = new File(newDir);
file.mkdir();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getProgramPath2() throws UnsupportedEncodingException {
URL url = MkDirForMe.class.getProtectionDomain().getCodeSource().getLocation();
String jarPath = URLDecoder.decode(url.getFile(), "UTF-8");
String parentPath = new File(jarPath).getParentFile().getPath();
return parentPath;
}
}
Even this isn't guaranteed to work, and you'll have to resign yourself to the fact that there are just some times (for instance for security reasons) when you won't be able to get a Jar's path.
With some changes (such as adding a "/" before Comics), I managed to create the directory where you expected it to. Here is the full code I used.
import java.io.*;
public class TestClass {
public static String getProgramPath() throws IOException{
String currentdir = System.getProperty("user.dir");
currentdir = currentdir.replace( "\\", "/" );
return currentdir;
}
public static void main(String[] argv) {
try {
String d = getProgramPath() + "/Comics/";
System.out.println("Making directory at " + d);
File dir = new File(d);//The name of the directory to create
dir.mkdir();//Creates the directory
}
catch (Exception e) { System.out.println("Exception occured" + e);}
}
}
In the future, please don't hard code things like "/" and such. Use built-in libraries which will ask the OS what is right in this case. This ensures the functionality doesn't break (as easily) cross platform.
Of course, catch the exception properly etc. This is just quick and dirty attempt to mold your code into something that works.

Categories