Read files in directory and (if any) copy to folder [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Copying files from one directory to another in Java
I have a folder (c:/InstallationFiles) with .jar files in it. i want to read through it and if the name equals test1 i want to copy it to a test1 folder, then if the name is test2 copy it to a test2 folder etc. this is what i have so far:
private static int copyJARFiles() {
resultCode = 0;
File installFolder = new File(Constants.WINDOWS + Constants.INSTALLATION_FOLDER);
File[] installFiles = installFolder.listFiles();
for (int i = 0; i < installFiles.length; i++) {
if (installFiles[i].equals("test1.jar")){
}
if (installFiles[i].equals("test2.jar")){
}
}
return resultCode;
}
not sure how to copy it then. im still a rookie.
thank you / kind regards

if you want to copy jar:
You can use apache IO api. Use the below code:
FileUtils.copy(sourceFile,destinationFile);
You can also use java 7. It contains direct function to copy files.
if you want extract jar:
You can use java.util.zip.*; package classes.
Please let me know if you need more explanation.

Not sure I fully understood your task but maybe this example will help you
for (File f : installFolder.listFiles()) {
if (f.getName().endsWith(".jar")) {
File targetDir = new File(installFolder, f.getName().replace(".jar", ""));
if (!targetDir.exists()) {
targetDir.mkdir();
}
File target = new File(targetDir, f.getName());
Files.copy(f.toPath(), target.toPath());
}
}
The main idea is that Java 7 provides us with Files.copy util

Related

How can I count files by file type?

I have a Java program that goes over all the folders and files inside a given folder and it prints them.
The issues is that now I want to count all the files in the folder by their extension. How can I do that?
This is my code so far:
package ut5_3;
import java.io.File;
import java.util.ArrayList;
import org.apache.commons.io.FilenameUtils;
public class UT5_3 {
ArrayList<String> extensionArray = new ArrayList<String>();
ArrayList<String> extensionArrayTemp = new ArrayList<String>();
public static void main(String[] args) {
File directoryPath = new File("C://Users//Anima//Downloads//MiDir");
File[] directoryContent = directoryPath.listFiles();
UT5_3 prueba = new UT5_3();
prueba.goOverDirectory(directoryContent);
}
public void goOverDirectory(File[] directoryContent) {
for (File content : directoryContent) {
if (content.isDirectory()) {
System.out.println("===========================================");
System.out.println("+" + content.getName());
goOverDirectory(content.listFiles()); // Calls same method again.
} else {
String directoryName = content.getName();
System.out.println(" -" + directoryName);
String fileExtension = FilenameUtils.getExtension(directoryName);
}
}
}
}
So far I've tried making two ArrayList. One to store all the extensions from all the files and another one to store the distinct extensions, but I got really confused and I didn't know how to continue with that idea.
If it is too complex, it'd be great if you could explain an easier way to do it too.
Thanks!
So if I understand you correctly, you want to store the count of all of the file extensions you see. Here is how I would approach it.
First initialize a map with a String as the key and int as the value, at the top of your class like so.
private HashMap<String, Integer> extensions = new HashMap<String, Integer>();
Then you can run this whenever you need to add an extension to the count.
String in = "exe";
if(extensions.containsKey(in))
extensions.put(in, extensions.get(in) + 1);
else
extensions.put(in, 1);
If you want to retrieve the count, simply run extensions.get(in).
If you didn't know already, a HashMap allows you to assign a key to a value. In this case, the key is the file extension and value is the count.
Good day
Using Java 8 or higher is actually not too difficult. First, you need to collect the items. Then, you need to group them by extension and create a map of extensions with the count.
public static void main(String[] args) throws IOException {
Path start = Paths.get("C:/Users/Hector/Documents");
List<String> fileNames = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(start)){
for (Path entry : stream) {
if (!Files.isDirectory(entry)) {
fileNames.add(entry.getFileName().toString());// add file name in to name list
}
}
}
fileNames.stream().map(String::valueOf)
.collect(Collectors.groupingBy(fileName -> fileName.substring(fileName.lastIndexOf(".")+1)))
.entrySet().forEach(entry -> {
System.out.println("File extension: " + entry.getKey() + ", Count: " + entry.getValue().size());
});
}
For my "Documents" directory
Produced the following output
File extension: zargo~, Count: 3
File extension: txt, Count: 1
File extension: exe, Count: 1
File extension: pdf, Count: 3
File extension: ini, Count: 1
File extension: log, Count: 1
File extension: svg, Count: 1
File extension: zargo, Count: 3
File extension: lnk, Count: 1
The reason why I chose this solution over using Files.walk() is because this method can throw an AccessDeniedException which is problematic when you need to traverse different folders. However, if you can control access to a folder by calling canRead() method on the file object, then you could use it. I personally don't like it and many Java developers have issue with that function.
You could modify by adding it to a function that could be called recursively if the current path is a directory. Since the OP requirement is unclear if the count has to be for a given folder or the folder and all subfolders, I decided to just show the count for the current folder.
One last observation, when collecting the extensions, notice that I pass to the substring function to start from the last index of the period character. This is important to capture the real extension for files with multiple periods in the name. For example: Setup.x64.en-US_ProPlusRetail_RDD8N-JF2VC-W7CC6-TVXJC-3YF3D_TX_PR_act_1_OFFICE_13.exe. In a file, the extension always starts after the last period.

Java Path Finder NumericValueChecker

I am trying to learn Java Path Finder (JPF). I downloaded the JPF and build it. Currently I have jpf-core folder which has example .java files together with their corresponding .jpf files. My goal is to create a new basic .java file and check whether a specific value in this file exceeds the max-bound I specified in the .jpf file.
In the examples folder there is .java file called NumericValueCheck.java which is exactly what I want, and it works as expected. (finds when the value exceeds the bound)
NumericValueCheck.java
public class NumericValueCheck {
public static void main (String[] args){
double someVariable;
someVariable = 42;
someVariable = 60;
}
}
NumericValueCheck.jpf
target = NumericValueCheck
listener = .listener.NumericValueChecker
# NumericValueChecker configuration
range.vars = 1
range.1.var = NumericValueCheck.main(java.lang.String[]):someVariable
range.1.min = 0
range.1.max = 42
However, I created a new .java file and named it "BasicCheck.java". Here is the code inside it;
public class BasicCheck {
public static void main(String[] args){
double result;
result = 60;
result = 110;
}
}
Here are the properties in BasicCheck.jpf;
target = BasicCheck
listener = .listener.NumericValueChecker
# NumericValueChecker configuration
range.vars = 1
range.1.var = BasicCheck.main(java.lang.String[]):result
range.1.min = 0
range.1.max = 60
I compiled the BasicCheck.java using javac BasicCheck.java in a separate directory. Then I copy "BasicCheck.java" and "BasicCheck.jpf" to examples folder of jpf-core where NumericValueCheck.java and NumericValueCheck.jpf also in the same place. I also copy "BasicCheck.class" to jpf-core/build/examples directory where "NumericValueCheck.class" also in the same place.
However, when I run the command java -jar build/RunJPF.jar src/examples/BasicCheck.jpf, it can't find any error. The result is "no error detected". It should detect 110 which is bigger than the upper bound 60.
Why is it not working? Do I need to add something extra to my new BasicCheck.java or BasicCheck.jpf ?
Thanks in advance.
I found the solution after a long effort. The solution is simple.
Put BasicCheck.java and BasicCheck.jpf under the directory jpf-core/src/examples.
Do NOT compile to source using javac. Open the terminal and cd to jpf-core directory. Then type the following command: ./gradlew buildJars.
That's it. Now you can use the command java -jar build/RunJPF.jar src/examples/BasicCheck.jpf to run Java Path Finder.

Return Not-Hidden Files [duplicate]

This question already has answers here:
How to negate a method reference predicate
(13 answers)
Closed 4 years ago.
Prior to Java 8, this method would be used to create a list of hidden files:
File[] hiddenFiles = new File("./directory/").listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isHidden();
}
});
In Java 8, this can be shortened to:
File[] hiddenFiles = new File("./directory/").listFiles(File::isHidden);
Returning non-hidden files in the original code was a trivial change: return file.!isHidden(); as a substitute for return file.isHidden();. I cannot recreate this functionality within a single line.
There is no isNotHidden function within the File class. Without creating one (or without deferring to the original, more verbose code), is there a way to recreate it using the new single-line style?
How about this,
File[] hiddenFiles = new File("c:/data").listFiles(f -> !f.isHidden());
Coming in java-11 Predicate.not, until then you can't via a method reference
Predicate.not(File::isHidden)

Searching files in a directory and pairing them based on a common sub-string

I have been attempting to program a solution for ImageJ to process my images.
I understand how to get a directory, run commands on it, etc etc. However I've run into a situation where I now need to start using some type of search function in order to pair two images together in a directory full of image pairs.
I'm hoping that you guys can confirm I am on the right direction and that my idea is right. So far it is proving difficult for me to understand as I have less than even a month's worth of experience with Java. Being that this project is directly for my research I really do have plenty of drive to get it done I just need some direction in what functions are useful to me.
I initially thought of using regex but I saw that when you start processing a lot of images (especially with imagej which it seems does not dump data usage well, if that's the correct way to say it) that regex is very slow.
The general format of these images is:
someString_DAPI_0001.tif
someString_GFP_0001.tif
someString_DAPI_0002.tif
someString_GFP_0002.tif
someString_DAPI_0003.tif
someString_GFP_0003.tif
They are in alphabetical order so it should be able to go to the next image in the list. I'm just a bit lost on what functions I should use to accomplish this but I think my overall while structure is correct. Thanks to some help from Java forums. However I'm still stuck on where to go to next.
So far here is my code: Thanks to this SO answer for partial code
int count = 0;
getFile("C:\");
string DAPI;
string GFP;
private void getFile(String dirPath) {
File f = new File(dirPath);
File[] files = f.listFiles();
while (files.length > 0) {
if (/* File name contains "DAPI"*/){
DAPI = File f;
string substitute to get 'GFP' filename
store GFP file name into variable
do something(DAPI, GFP);
}
advance to next filename in list
}
}
As of right now I don't really know how to search for a string within a string. I've seen regex capture groups, and other solutions but I do not know the "best" one for processing hundreds of images.
I also have no clue what function would be used to substitute substrings.
I'd much appreciate it if you guys could point me towards the functions best for this case. I like to figure out how to make it on my own I just need help getting to the right information. Also want to make sure I am not making major logic mistakes here.
It doesn't seem like you need regex if your file names follow the simple pattern that you mentioned. You can simply iterate over the files and filter based on whether the filename contains DAPI e.g. see below. This code may be oversimplification of your requirements but I couldn't tell that based on the details you've provided.
import java.io.*;
public class Temp {
int count = 0;
private void getFile(String dirPath) {
File f = new File(dirPath);
File[] files = f.listFiles();
if (files != null) {
for (File file : files) {
if (file.getName().contains("DAPI")) {
String dapiFile = file.getName();
String gfpFile = dapiFile.replace("DAPI", "GFP");
doSomething(dapiFile, gfpFile);
}
}
}
}
//Do Something does nothing right now, expand on it.
private void doSomething(String dapiFile, String gfpFile) {
System.out.println(new File(dapiFile).getAbsolutePath());
System.out.println(new File(gfpFile).getAbsolutePath());
}
public static void main(String[] args) {
Temp app = new Temp();
app.getFile("C:\\tmp\\");
}
}
NOTE: As per Vogel612's answer, if you have Java 8 and like a functional solution you can have:
private void getFile(String dirPath) {
try {
Files.find(Paths.get(dirPath), 1, (path, basicFileAttributes) -> (path.toFile().getName().contains("DAPI"))).forEach(
dapiPath -> {
Path gfpPath = dapiPath.resolveSibling(dapiPath.getFileName().toString().replace("DAPI", "GFP"));
doSomething(dapiPath, gfpPath);
});
} catch (IOException e) {
e.printStackTrace();
}
}
//Dummy method does nothing yet.
private void doSomething(Path dapiPath, Path gfpPath) {
System.out.println(dapiPath.toAbsolutePath().toString());
System.out.println(gfpPath.toAbsolutePath().toString());
}
Using java.io.File is the wrong way to approach this problem. What you're looking for is a Stream-based solution using Files.find that would look something like this:
Files.find(dirPath, 1, (path, attributes) -> {
return path.getFileName().toString().contains("DAPI");
}).forEach(path -> {
Path gfpFile = path.resolveSibling(/*build GFP name*/);
doSomething(path, gfpFile);
});
What this does is:
Iterate over all Paths below dirPath 1 level deep (may be adjusted)
Check that the File's name contains "DAPI"
Use these files to find the relevant "GFP"-File
give them to doSomething
This is preferrable to the files solution because of multiple things:
It's significantly more informative when failing
It's cleaner and more terse than your File-Based solution and doesn't have to check for null
It's forward compatible, and thus preferrable over a File-Based solution
Files.find is available from Java 8 onwards

Get the number of files in a folder, omitting subfolders

Is the any way to get the number of files in a folder using Java?
My question maybe looks simple, but I am new to this area in Java!
Update:
I saw the link in the comment. They didn't explained to omit the subfolders in the target folder.
How to do that? How to omit sub folders and get files in a specified directory?
Any suggestions!!
One approach with pure Java would be:
int nFiles = new File(filename).listFiles().length;
Edit (after question edit):
You can exclude folders with a variant of listFiles() that accepts a FileFilter. The FileFilter accepts a File. You can test whether the file is a directory, and return false if it is.
int nFiles = new File(filename).listFiles( new MyFileFilter() ).length;
...
private static class MyFileFilter extends FileFilter {
public boolean accept(File pathname) {
return ! pathname.isDirectory();
}
}
You will need to use the File class. Here is an example.
This method allows you to count files inside the folder without loading all files into memory at once (which is good considering folders with big amount of files which could crash your program), and you can additionaly check file extension etc. if you put additional condition next to f.isFile().
import org.apache.commons.io.FileUtils;
private int countFilesInDir(File dir){
int cnt = 0;
if( dir.isDirectory() ){
Iterator it = FileUtils.iterateFiles(dir, null, false);
while(it.hasNext()){
File f = (File) it.next();
if (f.isFile()){ //this line weeds out other directories/folders
cnt++;
}
}
}
return cnt;
}
Here you can download commons-io library: https://commons.apache.org/proper/commons-io/

Categories