Read files from directory using BufferedReader - java

I wrote a code to read a files from a directory.
The directory contain many files. Firstly, I count the number of the files in the directory, then I would like to count number of lines in the files that have as extension: .info and .data
My code is the following:
public void checkEmptyEntryFileLoader(String directory) {
File name = new File(directory);
String filenames[]=name.list();
long countFile = 0;
long countLineData = 0;
long countLineInfo = 0;
for(String filename:filenames){
//System.out.println(filename);
countFile++;
}
System.out.println(countFile); // this bloc worked well
File files[]=name.listFiles();
for(File file:files){
String fileName = file.getName();
if(fileName.endsWith("data")) {
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
while (reader.readLine() != null) {
countLineData++;
}
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fileName.endsWith("info")) {
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
while (reader.readLine() != null) {
countLineInfo ++;
}
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(countLineInfo );
}
}
I got as error:
java.io.FileNotFoundException: my_file_name.data (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at java.io.FileReader.<init>(FileReader.java:58)
The error concerns the FileReader, it accept only the string, and the filename is a String
Do you have some idea please ?
Thank you

Instead of passing filename in FileReader(), try passing file.
BufferedReader reader = new BufferedReader(new FileReader(file));
My answer assumes that the error that you have given as output is stack trace printed in the try-catch block and not the error that you get when you try to compile/run the code.

The answer by #SARVESH TANDON looks like will fix your issue and note that you scan the filesystem twice.
Consider using NIO and streams to scan large file systems, as File.list / File.listFiles perform very badly when number of files get big, or you need to scan deeper as they need to be repeated.
Here is example of code using NIO. It uses a filter to restrict the search to only files of the right extension, and you can vary the find depth=1 parameter to Integer.MAX_VALUE for deep scans, and handles exceptions:
Path dir = Path.of(directory);
long[] counts = new long[3]; // FILES, MATCHFILES, LINECOUNT
try(Stream<Path> stream = Files.find(dir, 1, (p, a) -> ++counts[0] > 0 && a.isRegularFile())) {
stream.filter(p -> { String fn = p.getFileName().toString();
return (fn.endsWith("data") || fn.endsWith("info")) && ++counts[1] > 0; })
.forEach(p -> {
try(Stream<String> lines = Files.lines(p)) {
long count = lines.count();
counts[2]+=count;
System.out.println("path: "+p+" lines:"+count);
} catch (IOException io) {
throw new UncheckedIOException(io);
}
});
}
System.out.println("Total files: "+(counts[0]-1)); // dir is counted too
System.out.println("Match files: "+counts[1]);
System.out.println("Total lines: "+counts[2]);

Related

Why keep receiving java.io.FileNotFoundException: (Access is denied) error?

I am trying to load image file from file directory. Then, I want to convert the file object to string object. Unfortunately, I keep receive this error messages. How can I resolve it?
java.io.FileNotFoundException: E:\workspace\sesaja\Images (Access is denied)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at java.io.FileInputStream.<init>(FileInputStream.java:79)
at test.Test1.main(Test1.java:29)
Thi is my overall code
public class Test1 {
public static void main(String args[]){
String s = System.getProperty("user.dir") + System.getProperty("file.separator")+ "Images";
File f = new File (s);
FileInputStream fis = null;
String str = "";
try {
fis = new FileInputStream(f);
int content;
while ((content = fis.read()) != -1) {
// convert to char and display it
str += (char) content;
}
System.out.println("After reading file");
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Concatenate desired file name at the end of this line:
String s = System.getProperty("user.dir") +
System.getProperty("file.separator")+ "Images" + fileName;
It seems you are trying to read data from a directory, which is not logically correct.
Also using FileInputStream in order to read characters (not data) is not recommended. You may use a BufferedReader instead.
Also for getting name of files inside a directory, you may read this: Read all files in a folder

How to check if a file exists in java

Im having a problem in checking if a file exists in Java. However the IF block seems to work , but the ELSE seems dont. see, when a file exist, it will prompt a box that says, 'File found.' which happens in my program whenever a file do exist, the problem is errors flood in my console when a file dont exist. Can somebody tell me what's the easier and shorter way of coding my problem? thanks ! here's my code
public void actionPerformed(ActionEvent e) {
BufferedReader br = null;
File f = new File(textField.getText());
String path = new String("C:\\Users\\theBeard\\workspace\\LeapYear\\");
try {
String sCurrentLine;
br = new BufferedReader(new FileReader(path+f));
if (f.exists())
{
JOptionPane.showMessageDialog(null, textField.getText()+" found" );
while ((sCurrentLine = br.readLine()) != null) {
textArea.append(sCurrentLine);
textArea.append(System.lineSeparator());
}
}
else
{
JOptionPane.showMessageDialog(null, textField.getText()+" not found" );
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (br != null)
{
br.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
});
The problem is with this line:
br = new BufferedReader(new FileReader(path+f));
You're appending a File to a String, which doesn't make sense. You should append a String to a String, in this case textField.getText()) appended to path.
This line will throw an exception if the file doesn't exist as per the documentation of FileReader:
Throws:
FileNotFoundException - if the named file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading.
This causes your program to reach the catch clause and print an exception stack trace. You should only call this line when f.exists() returns true:
if (f.exists())
{
br = new BufferedReader(new FileReader(path + textField.getText()));
...
}
Look at these lines of your code:
br = new BufferedReader(new FileReader(path+f));
if (f.exists())
You are trying to open the file before checking whether it exists. So if the attempt to open it fails with a FileNotFoundException, the test is never reached.
String path = "C:\\Path\\To\File\\Directory\\";
String fileName = "NameOfFile.ext";
File f = new File(path, fileName);
if(f.exists()) {
//<code for file existing>
} else {
//<code for file not existing>
}
You have to instantiate the BufferedReader after checking the existence of the file.
String path = new String("C:\\Users\\theBeard\\workspace\\LeapYear\\");
File f = new File(path + textField.getText());
...
if (f.exists())
{
br = new BufferedReader(new FileReader(f.getAbsolutePath())); // or br = new BufferedReader(f);
...

How can I count the number of files in a folder within a JAR?

I've spent a bit of time trying to find a way to count the number of files in a folder within a JAR. I put together several examples of code that served different purposes to make this work. It counts just fine when I run the code through Eclipse but after exporting to a JAR it fails and returns 0. In this case, my folder path I use is just "rules/". I would appreciate any recommendations or samples. Thanks.
public static int countFiles(String folderPath) throws IOException { //Counts the number of files in a specified folder
ClassLoader loader = ToolSet.class.getClassLoader();
InputStream is = loader.getResourceAsStream(folderPath);
try {
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1) {
empty = false;
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\n') {
++count;
}
}
}
return (count == 0 && !empty) ? 1 : count;
} finally {
is.close();
}
}
EDIT:
The following doesn't exactly match my original question but thanks to MadProgrammer I was able to reduce my code and eliminate the need to even count the files. The code blow searches every file in my JAR looking for those that end with ".rules", opens the file, searches the file for a string that matches "searchBox.getText()", appends results, and continues on to the next ".rules" file.
StringBuilder results = new StringBuilder();
int count = 0;
JarFile jf = null;
try {
String path = ToolSet.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
jf = new JarFile(new File(decodedPath));
Enumeration<JarEntry> entries = jf.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().endsWith(".rules")) {
String name = entry.getName();
InputStream in = ToolSet.class.getResourceAsStream(name);
InputStreamReader isr = new InputStreamReader(in);
BufferedReader bf = new BufferedReader(isr);
String line;
while ((line = bf.readLine()) != null) {
String lowerText = line.toLowerCase();
if(lowerText.indexOf(searchBox.getText().toLowerCase()) > 0) {
results.append(line + "\n");
count++;
}
}
bf.close();
}
}
} catch (IOException ex) {
try {
jf.close();
} catch (Exception e2) {
}
}
if(count>0) {
logBox.setText(results.toString());
} else {
logBox.setText("No matches could be found");
}
A Jar file is essentially a Zip file with a manifest.
Jar/Zip files don't actually have a concept of directories like disks do. They simply have a list of entries that have names. These names may contain some kind path separator and some entries may actually be marked as directories (and tend not to have any bytes associated with them, merely acting as markers)
If you want to find all the resources within a given path, you're going to have to open the Jar file and inspect it's entries yourself, for example...
JarFile jf = null;
try {
String path = "resources";
jf = new JarFile(new File("dist/ResourceFolderCounter.jar"));
Enumeration<JarEntry> entries = jf.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
String name = entry.getName();
name = name.replace(path + "/", "");
if (!name.contains("/")) {
System.out.println(name);
}
}
}
} catch (IOException ex) {
try {
jf.close();
} catch (Exception e) {
}
}
Now, this requires you to know the name of the Jar file you want to use, this may be problematic, as you may wish to list resources from a number of different Jars...
A better solution would be to generate some kind of "resource lookup" file at build time, which contained all the names of the resources that you might need, maybe even keyed to particular names...
This way you could simple use...
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsInputStream("/resources/MasterResourceList.txt")));
String name = null;
while ((name = br.readLine()) != null) {
URL url = getClass().getResource(name);
}
} finally {
try {
br.close();
} catch (Exception exp) {
}
}
For example...
You could even seed the file with the number of resources ;)
this is a simple solution :
InputStream is = loader.getResourceAsStream(folderPath);
//open zip
ZipInputStream zip = new ZipInputStream(is);
//count number of files
while ((zip.getNextEntry()) != null ) {
UnzipCounter++;
}

Replace filename contained in file and also rename file by new name using java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I've been trying to rename files and folders in a given folder by finding and replacing a substring in their name. Also, the name of file is contained in their contents also. I need to replace it to the new name.
For Example:
Change "XXX" to "KKK" in all the files and folder names and also in file contents:
Original file name: 0001_XXX_YYY_ZZZ.txt
New file name: 0001_KKK_YYY_ZZZ.txt
Following is the code that I'm using.
When I run the following code without calling the function replaceText(), its renaming the file and folder. But, when I try to change the text of file and then rename the file and folder; contents of file is changed but renaming of both file and folder fails.
Please help.
public class FindReplaceAnywhere {
public static void main(String[] args) {
String find = "XXX";
String replace = "KKK";
String baseLoc = "D:\\0001_XXX_YYY_ZZZ";
FindReplaceAnywhere obj = new FindReplaceAnywhere();
File baseLocObj = new File(baseLoc);
LinkedList<File> baseFolderList = new LinkedList<File>();
// Add base folder object to list
baseFolderList.add(baseLocObj);
// Get list of files in the folder
for(File file: baseLocObj.listFiles()) {
baseFolderList.add(file);
}
// Rename the files, folders & contents of files
obj.rename(baseFolderList, find, replace);
}
public void rename(LinkedList<File> fileList, String find, String replace) {
String tempStr = null;
int beginIndex = 0;
int endIndex = 0;
File tempFile;
System.out.println(">>> Batch Rename Process Begins >>>\n");
for(File aFile:fileList) {
// If Object is File, change the text also
if(aFile.isFile()) {
replaceText(aFile,find,replace);
}
}
for(File aFile: fileList) {
System.out.println("Processing>>>");
System.out.println(aFile.getPath());
if(aFile.getName().contains(find)) {
// Get the name of File object
beginIndex = aFile.getPath().length() - aFile.getName().length();
endIndex = aFile.getPath().length();
tempStr = aFile.getPath().substring(beginIndex, endIndex);
tempStr = tempStr.replace(find, replace);
}
else {
System.out.println("Error: Pattern not found\n");
continue;
}
tempFile = new File(aFile.getParentFile(),tempStr);
boolean success = aFile.renameTo(tempFile);
if(success) {
System.out.println("File Renamed To: "+tempFile.getName());
}
else {
System.out.println("Error: Rename Failed\nPossible Cause: File is open in another application");
}
System.out.println("");
}
}
/**
* Replace the text of file if it contains filename
*/
public void replaceText(File file, String find, String replace) {
String fullText = "";
String line = "";
String fileName = "";
String replaceName = "";
BufferedReader in;
BufferedWriter out;
// Read the file contents
try {
in = new BufferedReader(new FileReader(file));
while((line = in.readLine()) != null) {
fullText+=line+"\n";
}
}
catch(FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
// Replace the text of file
fileName = file.getName().substring(0, file.getName().indexOf("."));
replaceName = fileName.replace(find, replace);
fullText = fullText.replace(fileName, replaceName);
// Write the replaced text to file
try {
out = new BufferedWriter(new FileWriter(file));
out.write(fullText);
out.close();
}
catch(FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
It doesn't look like you're closing your input (in) file after reading it, which will hold that file open - Under *nix a rename should still work, but it will fail under Windows:
Use a finally block to ensure that the resource is closed.. but only after you're assured that it was opened.
While I'm at it, please allow me to suggest another change to the code:
Move "declarations" to the the absolute last point in the code where they can be made.. avoid declaring early. In this case, both in and out are unnecessarily declared early. There are others; I'll leave that for you to work out.
So, for the input file:
// Read the file contents
try {
BufferedReader in = new BufferedReader(new FileReader(file));
// If you got this far, the file is open...
// use try/finally to ensure closure.
try {
while((line = in.readLine()) != null) {
fullText+=line+"\n";
}
}
finally {
in.close();
}
}
catch(FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
and for the output file:
// Write the replaced text to file
try {
BufferedWriter out = new BufferedWriter(new FileWriter(file));
try {
out.write(fullText);
}
finally {
out.close();
}
}
catch(FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}

How to stop a program if file doesn't exist in a folder using java?

i have a program which select recent files from a directory and compress them into one file.
but i want to stop the program if there is no files in the directory and display an error message like "There is no files in the deirectory"
I tried append this:
if(file.exists)
{ }
else
{ }
but i don't know how to insert it inside my code.
Thank you
{
String source = "C:/Source";
String target = "C:/Target";
File sourceDir = new File(source);
File[] files = sourceDir.listFiles();
if(files.exists())
Arrays.sort(files, new Comparator<File>()
{
public int compare(File f1, File f2)
{
return (int) (f2.lastModified() - f1.lastModified());
}
});
// create the target directory
File targetDir = new File(target);
targetDir.mkdirs();
{
for(int i=0, length=Math.min(files.length, 12); i<length; i++)
files[i].renameTo(new File(targetDir, files[i].getName()));
PrintWriter pw = new PrintWriter(new FileOutputStream("C:/Joined/joined.txt"));
File file = new File("C:/Target");
File[] files2 = file.listFiles();
for (int i = 0; i < files2.length; i++)
{
File currentFile = files2[i];
System.out.println("Processing " + currentFile.getPath() + "... ");
BufferedReader br = new BufferedReader(new FileReader(currentFile));
String line = br.readLine();
while (line != null)
{
pw.println(line);
line = br.readLine();
}
br.close();
}
pw.close();
Thread.sleep(2000);
try
{
ProcessBuilder pb = new ProcessBuilder("c:\\Joined\\Join.bat");
Process p = pb.start();
}
catch (IOException e)
{
e.printStackTrace();
}
}}}
Instead of using System.exit() method it is better to use guard clauses to prevent further execution. Using System.exit() is not a good practice as it halts the flow abruptly. Ideal solution would be
if (file.exists())
return; //Use appropriate returns according to the method signature.
// Block of code that does something with the file.
You can try to call method exit like this:
System.exit(0);
Hope that helps.
If sourceDir does not refer to a directory, you'll get null from listFiles, so that's a first thing you could check.
If it indeed refers to a directory, and the directory is empty, you'll simply get an empty array back from listFiles. So you could use
if (files.length() == 0) {
System.err.println("There is no files in the deirectory");
System.exit(-1);
}
After
File[] files2 = file.listFiles();
you can do
if(files2.length == 0)
{
System.err.println("Error - no files found!");
and if you want the program to completely close,
System.exit(1); //0 denotes normal close, 1 denotes an error
}
and if you want the program to continue to the next step,
break; //exit the current loop
}
After the if(files.exists()), make sure to include brackets ({ and }) with all that chunk of code you just mentioned
For example:
if(files.exists()) {
// code you want it to run if files exist
} else System.err.println("No Files Exist In This Directory...")

Categories