Want to remove the whitespaces, with java built in methods - java

I have developed an application that read how many files are there in a java package inside the java project and count the line of code in those individual files to for example in a java project if there are 2 packages having 4 individual files then total files read will be 4 and if those 4 files having 10 piece of lines of code in each file then 4*10 is total 40 lines of code in overall project ...below is my piece of code
private static int totalLineCount = 0;
private static int totalFileScannedCount = 0;
public static void main(final String[] args) throws FileNotFoundException {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("C:" + File.separator));
chooser.setDialogTitle("FILES ALONG WITH LINE NUMBERS");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
Map<File, Integer> result = new HashMap<File, Integer>();
File directory = new File(chooser.getSelectedFile().getAbsolutePath());
List<File> files = getFileListing(directory);
// print out all file names, in the the order of File.compareTo()
for (File file : files) {
// System.out.println("Directory: " + file);
getFileLineCount(result, file);
//totalFileScannedCount += result.size(); //saral
}
System.out.println("*****************************************");
System.out.println("FILE NAME FOLLOWED BY LOC");
System.out.println("*****************************************");
for (Map.Entry<File, Integer> entry : result.entrySet()) {
System.out.println(entry.getKey().getAbsolutePath() + " ==> " + entry.getValue());
}
System.out.println("*****************************************");
System.out.println("SUM OF FILES SCANNED ==>" + "\t" + totalFileScannedCount);
System.out.println("SUM OF ALL THE LINES ==>" + "\t" + totalLineCount);
}
}
public static void getFileLineCount(final Map<File, Integer> result, final File directory)
throws FileNotFoundException {
File[] files = directory.listFiles(new FilenameFilter() {
public boolean accept(final File directory, final String name) {
if (name.endsWith(".java")) {
return true;
} else {
return false;
}
}
});
for (File file : files) {
if (file.isFile()) {
Scanner scanner = new Scanner(new FileReader(file));
int lineCount = 0;
totalFileScannedCount ++; //saral
try {
for (lineCount = 0; scanner.nextLine() != null; ) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
lineCount++;
}
}
} catch (NoSuchElementException e) {
result.put(file, lineCount);
totalLineCount += lineCount;
}
}
}
}
/**
* Recursively walk a directory tree and return a List of all Files found;
* the List is sorted using File.compareTo().
*
* #param aStartingDir
* is a valid directory, which can be read.
*/
static public List<File> getFileListing(final File aStartingDir) throws FileNotFoundException {
validateDirectory(aStartingDir);
List<File> result = getFileListingNoSort(aStartingDir);
Collections.sort(result);
return result;
}
// PRIVATE //
static private List<File> getFileListingNoSort(final File aStartingDir) throws FileNotFoundException {
List<File> result = new ArrayList<File>();
File[] filesAndDirs = aStartingDir.listFiles();
List<File> filesDirs = Arrays.asList(filesAndDirs);
for (File file : filesDirs) {
if (file.isDirectory()) {
result.add(file);
}
if (!file.isFile()) {
// must be a directory
// recursive call!
List<File> deeperList = getFileListingNoSort(file);
result.addAll(deeperList);
}
}
return result;
}
/**
* Directory is valid if it exists, does not represent a file, and can be
* read.
*/
static private void validateDirectory(final File aDirectory) throws FileNotFoundException {
if (aDirectory == null) {
throw new IllegalArgumentException("Directory should not be null.");
}
if (!aDirectory.exists()) {
throw new FileNotFoundException("Directory does not exist: " + aDirectory);
}
if (!aDirectory.isDirectory()) {
throw new IllegalArgumentException("Is not a directory: " + aDirectory);
}
if (!aDirectory.canRead()) {
throw new IllegalArgumentException("Directory cannot be read: " + aDirectory);
}
}
but the issue is that it also count the white space lines while calculating the line of code for the individual files , which it should not , please advise what modifications I need to do in my program so that it should not count the white spaces while calculating the line of code for the individual files .
The idea that was coming to my mind was just compares the read string with "", and count if not equals to "" (empty) like if(!readString.trim().equals("")) lineCount++
Please advise for this

Suggestions:
Scanner has a hasNextLine() method which you should use. I would use it as the condition of a while loop.
Then get the line inside the while loop by calling nextLine() just once inside of the loop.
Again call trim() on your Strings that are read in. I still don't see your attempt at this in the latest code update!
A key concept when calling methods on Strings is that they are immutable, and the methods called on them do not change the underlying String, and trim() is no different: The String that it is called on is unchanged, but the String returned by the method is changed, and in fact is trimmed.
String has an isEmpty() method that you should call after trimming the String.
So don't do:
try {
for (lineCount = 0; scanner.nextLine() != null; ) {
if(!readString.trim().equals("")) lineCount++; // updated one
}
} catch (NoSuchElementException e) {
result.put(file, lineCount);
totalLineCount += lineCount;
}
Instead do:
int lineCount = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
lineCount++;
}
}

Related

Improve Performance of Find and Replace in folder and subfolder files Java

I have a java program that do find and replace ( like when you do it in a text editor for example notepad++ ) in files of a folder and all sub-folders
well what i did is i created 4 functions the first function has folder path in the parameters
so it listed all the sub files if it's a folder then list all the sub files again and then on RecursivePrint i check the extension of the file if it's a non readable file like images and compressed files then ignore otherwise i open the file using BufferedReader and check for the string and replace it with the new string
public void findWord(File pathToStart){
// find word in every sub folders and subfiles.
File[] filesInDirectory = pathToStart.listFiles(); // all sub files listed
findWord = find.getText();
replaceWord = replace.getText();
driver();
}
public void driver(){ // drive all the files
File dir = new File(path.getText());
//fill here
if(dir.exists() && dir.isDirectory())
{
// array for files and sub-directories
// of directory pointed by maindir
File arr[] = dir.listFiles();
// Calling recursive method
RecursivePrint(arr,0,0);
}
public void RecursivePrint(File[] arr,int index,int level) //arr file array
{
// terminate condition
if(index == arr.length)
return;
// tabs for internal levels
for (int i = 0; i < level; i++)
System.out.print("\t");
// for files
if(arr[index].isFile()){
String fileNamee;
fileNamee=arr[index].getAbsolutePath();
if( fileNamee.contains(".png") == false && fileNamee.contains(".jpg") == false && fileNamee.contains(".jpeg") == false
&& fileNamee.contains(".rawproto") == false&& fileNamee.contains(".apk") == false && fileNamee.contains(".pro") == false){
modifyFile(fileNamee, findWord, replaceWord);
System.out.println("\nDoing The Task");
}
else{
//System.out.print("File Not Readaable might be img file or other on-readable file");
}
}
// for sub-directories
else if(arr[index].isDirectory() && !(arr[index].getName().equals(".git")))
{
// recursion for sub-directories
RecursivePrint(arr[index].listFiles(), 0, level + 1);
}
// recursion for main directory
RecursivePrint(arr,++index, level);
}
public static void modifyFile(String filePath, String oldString, String newString){
File fileToBeModified = new File(filePath);
String oldContent = "";
BufferedReader reader = null;
FileWriter writer = null;
try
{
reader = new BufferedReader(new FileReader(fileToBeModified));
//Reading all the lines of input text file into oldContent
String line = reader.readLine();
while (line != null)
{
oldContent = oldContent + line + System.lineSeparator();
line = reader.readLine();
}
//Replacing oldString with newString in the oldContent
String newContent = oldContent.replaceAll(oldString, newString);
//Rewriting the input text file with newContent
writer = new FileWriter(fileToBeModified);
writer.write(newContent);
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
//Closing the resources
reader.close();
writer.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
well this code is working perfectly but the problem is it takes too long even with a good pc for just a 64mb folder it's stay for more than 20 min so is there anyway that i can improve the performance of this program
What is really slow, is to use String concatenation, +.
This can easily be hundreds times slower.
public static void modifyFile(String filePath, String oldString, String newString)
throws IOException {
Path file = Paths.get(filePath);
String oldContent = Files.readString(file, Charset.defaultCharset());
String newContent = oldContent.replaceAll(oldString, newString);
if (!newContent.equalsOldContent)) {
Files.writeString(file, newContent, Charset.defaultCharset());
}
}
There are other goodies in Files, also for walking through all files, subdirectories recursively and such.

Find line number and content of a line and then find open same line number in another file JAVA

I got this code to open up a file and getting the line number, but if I want to open up another file where the content is not the same as the first file and find the same line number, how can I do that the best way? Where do I go from here?
I'm new to this site and to Java so please go easy on me...
public class c {
public static void main(String args[]) {
File file =new File("one.txt");
Scanner in = null;
try {
int counter = 0;
in = new Scanner(file);
while(in.hasNext()) {
counter++;
String line=in.nextLine();
if(line.contains("umbrella")) {
System.out.println(line + " line: " + counter);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
You can just open the other file, and read the lines and increment a counter (counter2) until your counter2 reaches your counter-Variable (from above code-snippet). You also have to notice if the file hasn't ended.
The Code is has many similar Elements like the one you already used in your question.
The best way would depend on the context at which you are developing. You could just create additional instances of File and Scanner classes to operate on a different file as you already done in your code and mentioned in comment already.
Another method would be to create a class that would process this for you. In this case you could use this class for an unlimited number of files that you need to accomplish the same.
public class FileLineCounter {
public FileLineCounter( String filename)
{
try
{
f = new File(filename);
s = new Scanner(f);
}
catch(FileNotFoundException ex)
{
ex.printStackTrace();
}
}
public int getLineNumber( String item)
{
counter = 0;
while( s.hasNext())
{
counter++;
String line = s.nextLine();
if (line.contains(item))
{
break;
}
}
return counter;
}
private File f;
private Scanner s;
private int counter;
};
package FileUtil;
import FileUtil.FileLineCounter;
public class Main {
public static void main(String[] args)
{
String file1 = "one.txt";
String file2 = "two.txt";
FileLineCounter f1 = new FileLineCounter(file1);
FileLineCounter f2 = new FileLineCounter(file2);
System.out.println( file1 + " line : " + f1.getLineNumber("umbrella"));
System.out.println( file2 + " line : " + f2.getLineNumber("umbrella"));
}
}

How to list all files within a directory and all its sub-directories

I've made a program that lists all file names in a desired directory of your extension choice. Now I want to and I don't know how to change it to list all files within sub-directories too. Do you have any ideas? Here's my code. Thanks!
import java.util.*;
import java.io.*;
public class Program {
public static void main(String str[]){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("1.Enter directory name:");
String adress = br.readLine();
System.out.println("2.Enter file extension:");
String exten = br.readLine();
File directory = new File(adress);
File[] f = directory.listFiles();
List<String> files = new ArrayList<String>();
List<String> valid = new ArrayList<String>();
List<String> names = new ArrayList<String>();
for(int i=0; i < f.length; i++){
if(f[i].isFile()){
files.add(f[i].getName());
}
}
for(int i=0; i < files.size(); i++){
if (files.get(i).endsWith(exten)){
valid.add(files.get(i));
}
}
for(int i=0; i < valid.size(); i++){
int pos = valid.get(i).lastIndexOf(".");
names.add(valid.get(i).substring(0, pos));
System.out.println(names.get(i));
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
If you can use Java 7 or 8 you could use the FileVisitor, but in Java 7 it means writing more then one line of code. If not and you want to keep it simple, Apache Commons FileUtils may be your friend.
Collection<File> files = FileUtils.listFiles(path, new String[]{"xlxs"}, true);
I made this awhile back to find all of *.xls or *.xlsx in a directory.
Hope this will help you with your question.
public static List<String> fileSearch(String d){
List<String> filesFound = new ArrayList<String>();
File dir = new File(d);
try{
for(File file: dir.listFiles()){
if(file.isFile() && (file.getName().toLowerCase().endsWith(".xlsx") || file.getName().toLowerCase().endsWith(".xls"))){
long filesize = file.length();
long fileSize = filesize / 1024;
filesFound.add(d + "\\" + file.getName());
System.out.println("Added: " + d + "\\" + file.getName() + " " + fileSize + " KB" );
}else if(file.isDirectory() && !file.isHidden()){
System.out.println("Found Directory: " + file.getName());
filesFound.addAll(fileSearch(d + "\\" + file.getName()));
}else if(isRoot(file)){
//DO NOTHING
}
}
}catch(NullPointerException ex){
ex.printStackTrace();
}finally{
return filesFound;
}
}
private static boolean isRoot(File file){
File[] roots = File.listRoots();
for (File root : roots) {
if (file.equals(root)) {
return true;
}
}
return false;
}
What this does, it will search every file for a match and if it matches then it will add it to the array "filesFound" from there you can get all the paths of matched files. BUT for you, you would take out the .xlsx and .xls part and add in your ext.
fileSearch(String d, String ext)
and change the if then to:
if(file.isFile() && file.getName().toLowerCase().endsWith(ext))
ALSO i have it outputting when ever it finds a match with the file size next to it. The file size is just a visual aid and does not get included in the array.

How do I concatenate sequential files in order with Java?

I have a directory that contains sequentially numbered log files and some Excel spreadsheets used for analysis. The log file are ALWAYS sequentially numbered beginning at zero, but the number of them can vary. I am trying to concatenate the log files, in the order they were created into a single text file which will be a concatenation of all the log files.
For instance, with log files foo0.log, foo1.log, foo2.log would be output to concatenatedfoo.log by appending foo1 after foo0, and foo2 after foo1.
I need to count all the files in the given directory with the extension of *.log, using the count to drive a for-loop that also generates the file name for concatenation. I'm having a hard time finding a way to count the files using a filter...none of the Java Turtorials on file operations seem to fit the situation, but I'm sure I'm missing something. Does this approach make sense? or is there an easier way?
int numDocs = [number of *.log docs in directory];
//
for (int i = 0; i <= numberOfFiles; i++) {
fileNumber = Integer.toString(i);
try
{
FileInputStream inputStream = new FileInputStream("\\\\Path\\to\\file\\foo" + fileNumber + ".log");
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
try
{
BufferedWriter metadataOutputData = new BufferedWriter(new FileWriter("\\\\Path\\to\\file\\fooconcat.log").append());
metadataOutputData.close();
}
//
catch (IOException e) // catch IO exception writing final output
{
System.err.println("Exception: ");
System.out.println("Exception: "+ e.getMessage().getClass().getName());
e.printStackTrace();
}
catch (Exception e) // catch IO exception reading input file
{
System.err.println("Exception: ");
System.out.println("Exception: "+ e.getMessage().getClass().getName());
e.printStackTrace();
}
}
how about
public static void main(String[] args){
final int BUFFERSIZE = 1024 << 8;
File baseDir = new File("C:\\path\\logs\\");
// Get the simple names of the files ("foo.log" not "/path/logs/foo.log")
String[] fileNames = baseDir.list(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return name.endsWith(".log");
}
});
// Sort the names
Arrays.sort(fileNames);
// Create the output file
File output = new File(baseDir.getAbsolutePath() + File.separatorChar + "MERGED.log");
try{
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(output), BUFFERSIZE);
byte[] bytes = new byte[BUFFERSIZE];
int bytesRead;
final byte[] newLine = "\n".getBytes(); // use to separate contents
for(String s : fileNames){
// get the full path to read from
String fullName = baseDir.getAbsolutePath() + File.separatorChar + s;
BufferedInputStream in = new BufferedInputStream(new FileInputStream(fullName),BUFFERSIZE);
while((bytesRead = in.read(bytes,0,bytes.length)) != -1){
out.write(bytes, 0, bytesRead);
}
// close input file and ignore any issue with closing it
try{in.close();}catch(IOException e){}
out.write(newLine); // seperation
}
out.close();
}catch(Exception e){
throw new RuntimeException(e);
}
}
This code DOES assume that the "sequential naming" would be zero padded such that they will lexigraphically (?? sp) sort correctly. i.e. The files would be
0001.log (or blah0001.log, or 0001blah.log etc)
0002.log
....
0010.log
and not
1.log
2.log
...
10.log
The latter pattern will not sort correctly with the code I have given.
Here's some code for you.
File dir = new File("C:/My Documents/logs");
File outputFile = new File("C:/My Documents/concatenated.log");
Find the ".log" files:
File[] files = dir.listFiles(new FilenameFilter() {
#Override
public boolean accept(File file, String name) {
return name.endsWith(".log") && file.isFile();
}
});
Sort them into the appropriate order:
Arrays.sort(files, new Comparator<File>() {
#Override
public int compare(File file1, File file2) {
return numberOf(file1).compareTo(numberOf(file2));
}
private Integer numberOf(File file) {
return Integer.parseInt(file.getName().replaceAll("[^0-9]", ""));
}
});
Concatenate them:
byte[] buffer = new byte[8192];
OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile));
try {
for (File file : files) {
InputStream in = new FileInputStream(file);
try {
int charCount;
while ((charCount = in.read(buffer)) >= 0) {
out.write(buffer, 0, charCount);
}
} finally {
in.close();
}
}
} finally {
out.flush();
out.close();
}
By having the log folder as a File object, you can code like this
for (File logFile : logFolder.listFiles()){
if (logFile.getAbsolutePath().endsWith(".log")){
numDocs++;
}
}
to find the number of log files.
I would;
open the output file once. Just use a PrintWriter.
in a loop ...
create a File for each possible file
if it doesn't exist break the loop.
Using a BufferedReader
to read the lines of the file with readLine()
write each line to the output file.
You should be able to do this with about 12 lines of code. I would pass the IOExceptions to the caller.
You can use SequenceInputStream for concatenation of FileInputStreams.
To see all log files File.listFiles(FileFilter) can be used.
It will give you unsorted array with files. To sort files in right order, use Arrays.sort.
Code example:
static File[] logs(String dir) {
File root = new File(dir);
return root.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.isFile() && pathname.getName().endsWith(".log");
}
});
}
static String cat(final File[] files) throws IOException {
Enumeration<InputStream> e = new Enumeration<InputStream>() {
int index;
#Override
public boolean hasMoreElements() {
return index < files.length;
}
#Override
public InputStream nextElement() {
index++;
try {
return new FileInputStream(files[index - 1]);
} catch (FileNotFoundException ex) {
throw new RuntimeException("File not available!", ex);
}
}
};
SequenceInputStream input = new SequenceInputStream(e);
StringBuilder sb = new StringBuilder();
int c;
while ((c = input.read()) != -1) {
sb.append((char) c);
}
return sb.toString();
}
public static void main(String[] args) throws IOException {
String dir = "<path-to-dir-with-logs>";
File[] logs = logs(dir);
for (File f : logs) {
System.out.println(f.getAbsolutePath());
}
System.out.println();
System.out.println(cat(logs));
}

Reading the java files from the folder

I have developed an application that reads files from the folder chosen by the user. It displays how many lines of code are in each file. I want only Java files to be shown in the file-chooser (files having .java extension). Below is my code:
public static void main(String[] args) throws FileNotFoundException {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("C:" + File.separator));
chooser.setDialogTitle("FILES ALONG WITH LINE NUMBERS");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{ Map<String, Integer> result = new HashMap<String, Integer>();
File directory = new File(chooser.getSelectedFile().getAbsolutePath());
int totalLineCount = 0;
File[] files = directory.listFiles(new FilenameFilter(){
#Override
public boolean accept(File dir, String name) {
return name.matches("\\*\\.java");
}
}
);
for (File file : files)
{
if (file.isFile())
{ Scanner scanner = new Scanner(new FileReader(file));
int lineCount = 0;
try
{ for (lineCount = 0; scanner.nextLine() != null; lineCount++) ;
} catch (NoSuchElementException e)
{ result.put(file.getName(), lineCount);
totalLineCount += lineCount;
}
} }
System.out.println("*****************************************");
System.out.println("FILE NAME FOLLOWED BY LOC");
System.out.println("*****************************************");
for (Map.Entry<String, Integer> entry : result.entrySet())
{ System.out.println(entry.getKey() + " ==> " + entry.getValue());
}
System.out.println("*****************************************");
System.out.println("SUM OF FILES SCANNED ==>"+"\t"+result.size());
System.out.println("SUM OF ALL THE LINES ==>"+"\t"+ totalLineCount);
}
I have editied also but still it is not working please advise
please advise how to read only the files having .java as an extension in other words only java files from the folder ,please advise
You need a FilenameFilter. This should work for you:
FilenameFilter javaFileFilter= new FilenameFilter() {
#Override
public boolean accept(File logDir, String name) {
return name.endsWith(".java")
}
};
You should look upon Filtering the list of Files in JFileChooser.
It has an example of ImageFilter.java which shows only image files in file chooser.

Categories