Deleting all files & directories except those matching a given glob pattern - java

I have a list of all the files & directories that I need to delete, but I need to exclude all files/directories that match a given glob pattern. Any suggestions on how I can achieve this?
I am currently using the FileUtils class to delete files like this -
for (File path : cleanableFiles) {
try {
FileUtils.deleteQuietly(path);
FileUtils.deleteDirectory(path);
} catch (Exception exception) {
}
}
cleanableFiles is Set<File>. I also have a glob pattern string (e.g '*.txt' to match all files that have .txt extension). I need to not delete the files/directories that match the glob pattern.

You can accomplish this in Java by using the java.nio.file.Files and java.nio.file.Path classes, and by using the java.nio.file.FileSystem class to create a PathMatcher that can match against a glob pattern.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.PathMatcher;
import java.nio.file.FileSystems;
import java.io.IOException;
import java.util.List;

Related

Is there a way to read programmatically a .jmod file in Java?

I opened a .jmod file with 7-zip and I can see the contents. I tried to read it with ZipInputStream programmatically but it doesn't work: does someone know how to do it?
There is no documentation in JEP 261: Module System regarding the format used by JMOD files. That's not an oversight, as far as I can tell, because leaving the format as an implementation detail means they can change the format, without notice, whenever they want. That being said, currently JMOD files appear to be packaged in the ZIP format; this other answer quotes the following from JEP 261:
The final format of JMOD files is an open issue, but for now it is based on ZIP files.
However, I can't find that quote anywhere in JEP 261. It looks to be from an older version of the specification—at least, I found similar wording in the history of JDK-8061972 (the issue associated with the JEP).
What this means is you should—for the time being—be able to read a JMOD file by using any of the APIs which allow reading ZIP files. For instance, you could use one of the following:
The java.util.zip API:
import java.io.File;
import java.io.IOException;
import java.util.zip.ZipFile;
public class Main {
public static void main(String[] args) throws IOException {
var jmodFile = new File(args[0]).getAbsoluteFile();
System.out.println("Listing entries in JMOD file: " + jmodFile);
try (var zipFile = new ZipFile(jmodFile)) {
for (var entries = zipFile.entries(); entries.hasMoreElements(); ) {
System.out.println(entries.nextElement());
}
}
}
}
Note: To read the contents of an entry, see ZipFile#getInputStream(ZipEntry).
The ZIP FileSystemProvider API:
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) throws IOException {
var jmodFile = Path.of(args[0]).toAbsolutePath().normalize();
System.out.println("Listing entries in JMOD file: " + jmodFile);
try (var fileSystem = FileSystems.newFileSystem(jmodFile)) {
Files.walk(fileSystem.getRootDirectories().iterator().next())
.forEachOrdered(System.out::println);
}
}
}
Note: To read the contents of an entry, use one of the many methods provided by the java.nio.file.Files class.
Note: The Path#of(String,String...) method was added in Java 11 and the FileSystems#newFileSystem(Path) method was added in Java 13. Replace those method calls if using an older version of Java.
To reiterate, however: The format used by JMOD files is not documented and may change without notice.

How to create an ArrayList of Text Files in Java?

I'm trying to create an ArrayList of pre-existing text files (basically take a folder of text files that are already saved on my computer and plug them into an ArrayList) so that I can iterate over them and send matching pairs of text files to another program (a separate java program) for data analysis. Is it possible to create an ArrayList of text files the way I want to?
Ever since the java.nio package was introduced, this has become simple enough, especially with Java 8 streams:
Files.walk(new File("/your/base/dir").toPath()) // stream of all files inside base folder
.filter(p->p.getFileName().endsWith(".txt")) // limit to .txt files
.map(Path::toAbsolutePath) // convert to absolute pathy
.forEach(System.out::println); // print
See: Files.walk(path, option...)
In apache commons-io, there is a class called FileUtils which will return a List of Files.
package test;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.commons.io.FileUtils;
public class TestFiles {
public static void main(String[] args) throws IOException {
File dir = new File("<dir>");
String[] extensions = new String[] { "txt" };
List<File> files = (List<File>) FileUtils.listFiles(dir, extensions, true);
}
}

Java-Copy file.txt inside org which is a folder in A.jar without extracting z.jar file

I was trying to copy a file into a A.jar (without extracting it) but it didn't work. Suppose I have file "copy.txt" in "D:\java\copy.txt" and i want this file to be copied into my "A.jar/org/here" . if the file is already exist then it should replace it.
i tried modifying the below code but it didn't work.
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class deploy {
public static void main(String[] argv) {
Path myFilePath = Paths.get("C:/Users/ma329300/Desktop/copy.txt");
Path zipFilePath = Paths.get("D:/java/A.jar");
try( FileSystem fs = FileSystems.newFileSystem(zipFilePath, null) ){
Path fileInsideZipPath = fs.getPath("/org/copy.txt");
Files.copy(myFilePath, fileInsideZipPath);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
First of all, check your paths. Java is really tricky with the paths and should be in full path form.
Try putting the backslashes like "D:\java\A.jar", as windows works differently than linux.
Also, if you change your file and re-compile, it will generate a new .jar each time, with the updated file you wanted to change. That would solve your problem without having to access your .jar externally.
I tried once to access libraries packed on a .jar and load them with the code inside the .jar too and didn't worked propperly, so be carefull.
Another thing you should be aware of is that you cannot modify a .jar directly without decompressing, as it uses a special algorythm in order to get the indexation properly done for and by java. Changing one specific part of the .jar could corrupt the data into it and make it crash on the run.
Hope it helped.

Unpack whole Tar easily in Java

Easiest way to unpack Tar (or BZip+Tar) archive in Java.
Apache Commons Compress has classes for unpacking Tar. But you have to iterate through all archive entries and save each entry's InputStream to file.
Is there way to simple unpack all files from Tar archive "in one line of code"?
I think your best bet is to launch as a subprocess. These libraries work with filesystem entries. So there is no easy way of doing it in one line of code
ProcessBuilder pb = new ProcessBuilder();
pb.directory(new File("path to your tar"));
pb.command("tar", "-xzvf", "my tar");
pb.start();
Plexus Archiver can do it.
But it also requires dependencies on plexus-container:
org.codehaus.plexus:plexus-archiver:3.4
org.codehaus.plexus:plexus-container-default:1.7.1
Example:
import org.codehaus.plexus.archiver.tar.TarUnArchiver;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContaining;
public class UnpackTarTest {
#Test
public void wholeTarAtOnce() throws IOException {
File srcFile = new File(getClass().getResource("my.tar").getFile());
File destDir = Files.createTempDirectory("UnpackTarTest_").toFile();
destDir.deleteOnExit();
final TarUnArchiver ua = new TarUnArchiver();
ua.setSourceFile(srcFile);
ua.enableLogging(new ConsoleLogger(Logger.LEVEL_DEBUG, "console_logger"));
ua.setDestDirectory(destDir);
ua.extract();
assertThat(destDir.list(), arrayContaining("mytar"));
}
}

In Codename One, why can I not get FileInputStream to import or compile?

Here are my imports:
import com.codename1.ui.*;
import com.codename1.ui.util.*;
import com.codename1.ui.plaf.*;
import com.codename1.ui.events.*;
import com.codename1.io.*;
import com.codename1.ui.layouts.*;
import java.io.*;
I cannot get this code to compile:
InputStream in = new FileInputStream("users.csv");
Here is the error:
C:\Users\Isaac\Documents\NetBeansProjects\CodenameOne_TESTING\src\com\fakecompany\testapp\MyApplication.java:119: error: cannot find symbol
InputStream in = new FileInputStream("users.csv");
symbol: class FileInputStream
location: class MyApplication
I thought this might be a problem with the imports, and sure enough, when I specifically imported java.io.FileImputStream it gave me an additional error:
C:\Users\Isaac\Documents\NetBeansProjects\CodenameOne_TESTING\src\com\fakecompany\testapp\MyApplication.java:13: error: cannot find symbol
import java.io.FileInputStream;
symbol: class FileInputStream
location: package java.io
What is going on? Is there a different way I am supposed to import files in Codename One? Let me know if this is not enough of my code to find the error.
PS: I need to get an input stream implemented so I can parse the csv file:
CSVParser parser = new CSVParser();
String[][] data = parser.parse(in);
It looks like Codename One has omitted that class - and others, I suspect.
Judging by the documentation, I suspect you want to use the com.codename1.io.FileSystemStorage class and its openInputStream method.
You may well want to watch the video on storing data to persistent storage too.
Jon's answer is correct but partial. The question is where is the CSV file actually stored...
If the file is in the src folder (part of your jar) use Display.getInstance().getResourceAsStream(getClass(), "/filename");.
If you downloaded it, then its very likely you downloaded to storage and not necessarily file system (slightly different things in mobile). Both have rather detailed API's to open/write and the Util class has a nice download API. Keep in mind that you can't just "put" a file on the device like you can in a computer, the filesystem is quite different.
As a sidenote, Codename One has a builtin CSVParser class which could be useful for you.

Categories