How to create an ArrayList of Text Files in Java? - 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);
}
}

Related

Reading File from another Package in Java using getResourceAsStream()

I am trying to read a file called "numbers.txt" which is filled with int numbers (one int per line, no empty lines). I want to put the numbers into an array and return this array (method readIntsFromFile). Unfoutnetly the File does not get found, so the InputStream cls returns null. If I put the file "numbers.txt" into the same folder as the Class ReadFileInput it works but I do not know why it does not work if I put the "numbers.txt" file into the resources folder. I thought getResourceAsStream() can get it there? The main just creates a new class Object and calls the class function with the parameter "numbers.txt" and saves the result in an array.
Here is the Class with the method readIntsFromFile:
package impl;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class ReadFileInput {
public int[] readIntsFromFile(String path) {
ArrayList<Integer> arrList = new ArrayList<>();
try {
InputStream cls = ReadFileInput.class.getResourceAsStream(path);
System.out.println("Get Resources as Stream: " + cls);
//Put cls in ArrayList
}
cls.close();
} catch (Exception e) {
System.out.println(e);
}
int[] arr = arrList.stream().mapToInt(Integer::intValue).toArray();
System.out.println(arr);
return arr;
}
}
Do you know how it could work?
All the best!
The string value you pass to SomeClass.class.getResource() (as well as getResourceAsStream, of course) has two 'modes'.
It looks 'relative to the package of SomeClass', which means, effectively, if you ask for e.g. "img/load.png", and SomeClass is in the package com.foo, you're really asking for "/com/foo/img/load.png" - this is relative mode.
You want to go into absolute mode: You want the 'classpath source' that provided the SomeClass.class file that the JVM used to load the code for SomeClass, and then look in that same place for, say, /img/load.png from there. In other words, if SomeClass's code was obtained by loading the bytecode from jar file entry /com/foo/SomeClass.class in jarfile myapp.jar, you want the data obtained by loading the jar file entry /img/load.png from jarfile myapp.jar. You can do that - simply start with a slash.
Given that your numbers.txt file appears to be in the 'root' of resources, that would strongly suggest the string you pass to .getResourceAsStream() should be "/numbers.txt". Note the leading slash.
NB: It's not quite a path. .. and such do not work. Weirdly, com.foo.numbers.txt would, if the jar file contains /com/foo/numbers.txt.

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.

FileWriter cycling through Arraylist but not writing to text file

I'm creating a log in form in Java and I've added a remember me method to store the log in data in a local text file for future us.
The premise is that once the checkbox is checked, the email and password gets written out to the text file.
Here's the code below:
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
public void rememberMe() throws IOException {
private final ArrayList<String> storage = new ArrayList<String>();
protected String storPass;
protected String storEmail;
storage.add(storEmail);
storage.add(storPass);
FileWriter writer = new FileWriter("local.txt");
for(String i : storage) {
writer.write(i);
System.out.println("We have written " + i);
}
writer.close();
}
with the output being:
We have written EMAILADDRESS
We have written PASSWORD
The data has been removed, but the printing in the foreach look is showing me that it's cycling through the Arraylist correctly.
The local.txt doesn't have any data in it, it's empty before running and empty during and after the program is ran.
Can anybody spot the problem I'm having?
Thanks in advance.
Instead of Using relative path use absolute path like D:\\local.txt. It will work
Try using:
Path locates/creates the file on the system
Then use the Files object to statically write the file using your list.
Path file = Paths.get("local.txt");
Files.write(file, storage, Charset.forName("UTF-8"));
This way you can stay away from writing explicit foreach loop.
here is more on the Files object which is available since java 1.7+
https://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html

How to read from files with Files.lines(...).forEach(...)?

I'm currently trying to read lines from a text only file that I have. I found on another stackoverflow(Reading a plain text file in Java) that you can use Files.lines(..).forEach(..)
However I can't actually figure out how to use the for each function to read line by line text, Anyone know where to look for that or how to do so?
Sample content of test.txt
Hello
Stack
Over
Flow
com
Code to read from this text file using lines() and forEach() methods.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class FileLambda {
public static void main(String args[]) {
Path path = Paths.of("/root/test.txt");
try (Stream<String> lines = Files.lines(path)) {
lines.forEach(s -> System.out.println(s));
} catch (IOException ex) {
// do something or re-throw...
}
}
}
Avoid returning a list with:
List<String> lines = Files.readAllLines(path); //WARN
Be aware that the entire file is read when Files::readAllLines is called, with the resulting String array storing all of the contents of the file in memory at once.
Therefore, if the file is significantly large, you may encounter an OutOfMemoryError trying to load all of it into memory.
Use stream instead: Use Files.lines(Path) method that returns a Stream<String> object and does not suffer from this same issue.
The contents of the file are read and processed lazily, which means that only a small portion of the file is stored in memory at any given time.
Files.lines(path).forEach(System.out::println);
With Java 8, if file exists in a classpath:
Files.lines(Paths.get(ClassLoader.getSystemResource("input.txt")
.toURI())).forEach(System.out::println);
Files.lines(Path) expects a Path argument and returns a Stream<String>. Stream#forEach(Consumer) expects a Consumer argument. So invoke the method, passing it a Consumer. That object will have to be implemented to do what you want for each line.
This is Java 8, so you can use lambda expressions or method references to provide a Consumer argument.
I have created a sample , you can use the Stream to filter/
public class ReadFileLines {
public static void main(String[] args) throws IOException {
Stream<String> lines = Files.lines(Paths.get("C:/SelfStudy/Input.txt"));
// System.out.println(lines.filter(str -> str.contains("SELECT")).count());
//Stream gets closed once you have run the count method.
System.out.println(lines.parallel().filter(str -> str.contains("Delete")).count());
}
}
Sample input.txt.
SELECT Every thing
Delete Every thing
Delete Every thing
Delete Every thing
Delete Every thing
Delete Every thing
Delete Every thing

How can I get the files on a zip as a Files[] array? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I list the files inside a JAR file?
That's mainly the question, how to get the files inside a zip file as an array of files
Apart from extracting the files from the zip, I don't know an URI scheme that references a file directly in the zip file. So you will end with a list of filenames as String not File instances.
So you may use classes like ZipFile, ZipEntry, input streams and son on to extract files from the Zip, then you can have a File instance referencing it in an array.
The simple answer is that you can't. A File is essentially an abstracted file system path for an object in the host operating system's file system. But a file in a ZIP file is not an object in the filesystem, and therefore doesn't have a file system path.
Think about it. Can you formulate a <pathname> for a ZIP file entry that would allow you to (say) run cat <pathname> on Linux? Or something similar on Windows?
So what can you do?
You could extract the ZIP file to the file system (using an external command would be simplest) and then refer to the files containing the extracted entries. You would need to mess around a bit to turn the ZIP's directory structure into the corresponding pathnames.
You could use ZipEntry objects instead of File objects ... though I think that they will only be valid / usable while the Zip file remains open.
You could find ... or write a Java 7-style FileSystem implementation that allowed you to treat a ZIP file as a file system. But those API's don't use File objects, etcetera.
If your operating system supported it, you could "mount" the ZIP file as a file system, and then File would work. For example: http://en.wikipedia.org/wiki/Filesystem_in_Userspace plus http://code.google.com/p/fuse-zip/
You may want to check out java.util.zip package that has utilities to unzip files.
Also check out the Apache Commons Compress api there are a few example on how to get started http://commons.apache.org/compress/examples.html
Update
To get an array of files inside a zip, they must first be extracted into a temporary location:
import java.util.zip.*;
import java.io.File;
import java.util.ArrayList;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.io.IOException;
public class ZipFileExtractor {
public static void main(String[] args) {
File[] zipFiles = ZipFileExtractor.getFileArray("archive.zip");
System.out.println(zipFiles.length);
}
public static File[] getFileArray(String archiveFileName) {
ArrayList<File> zipArrayList = new ArrayList<File>();
try {
ZipFile zFile = new ZipFile(archiveFileName);
for (Enumeration<? extends ZipEntry> e = zFile.entries(); e.hasMoreElements(); ) {
ZipEntry zEntry = e.nextElement();
InputStream in = zFile.getInputStream(zEntry);
File temp = File.createTempFile(zFile.getName(), null);
temp.deleteOnExit();
FileOutputStream out = new FileOutputStream(temp);
byte[] buffer = new byte[1024];
while (in.read(buffer) != -1) {
out.write(buffer);
}
zipArrayList.add(temp);
}
} catch (IOException e) {
}
return zipArrayList.toArray(new File[zipArrayList.size()]);
}
}
 
 
There is an API class called ZipInputStream in java.util.zip package.
It has a bunch of methods, among them getNextEntry() that pretty much does it:
ArrayList<ZipEntry> zipArrayList = new ArrayList<ZipEntry>();
ZipInputStream zis = ZipInputStream(new FileInputStream("archive.zip"));
while ((ZipEntry ze = zis.getNextEntry()) != null) {
zipArrayList.add(ze.getName());
}
I haven't tried compiling the above code, so it might have a few issues but I hope the idea is clear.

Categories