1
\$\begingroup\$

I have a Java program that does find and replace (like when you do it in a text editor for example notepad++) in files of a folder and all sub-folders.

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: then in 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.

    package test;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.event.*;
import java.awt.*; 
import java.io.*;  
import java.nio.file.Files;
import java.nio.channels.FileChannel;
import java.nio.file.StandardCopyOption;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Scanner;
import java.net.URL;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.*;
import java.nio.file.*; 
import java.io.IOException; 
import java.awt.image.*;
import  javax.imageio.*;

class FileSystem{
    JFrame frame;
    JLabel pathLabel, findLabel, replaceLabel, imageLabel, fbLabel, appLabel; // labels
    JTextField path,  find, replace, image, fbId, appName; // fields
    JButton browse; // button that will search for files
    JButton start; // button to execute the program 
    
    File fileSelectedViaChooser;
    File fileDirectory;

    private String findWord, replaceWord;
    FileSystem(){
        frame = new JFrame("File System"); // title of the Frame passed
        frame.setSize(600,530);  ///Frame Size 600width and 550Height
        frame.setLayout(null); //No built-in layout being used
        frame.setLocationRelativeTo(null); //Frame must be at centre position
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //On Closing the Frame program shall terminate

        pathLabel = new JLabel("Path");  //Creating a Label for Path
        pathLabel.setFont(new Font("Serif", Font.BOLD, 20)); // setting Font Style and Size for Label
        pathLabel.setBounds(80,50,50,30); // Giving Label a location in Frame
        frame.add(pathLabel); // adding Label in Frame

        path = new JTextField(); // initialized textField here
        path.setToolTipText("Add Path of the directory here");  // adding a tool tip when cursor is placed o field
        path.setFont(new Font("Serif", Font.PLAIN, 18)); // setting fonts
        path.setBounds(165,50,350,32); // adding position of field in the Frame
        frame.add(path); // adding Field in the frame

        findLabel = new JLabel("Find");  //Creating a Label for Find
        findLabel.setFont(new Font("Serif", Font.BOLD, 20)); // setting Font Style and Size for Label
        findLabel.setBounds(80,90,50,30); // Giving Label a location in Frame
        frame.add(findLabel); // adding Label in Frame


        find = new JTextField(); // initialized textField here
        find.setToolTipText("Word to find");  // adding a tool tip when cursor is placed o field
        find.setFont(new Font("Serif", Font.PLAIN, 18)); // setting fonts
        find.setBounds(165,90,350,32); // adding position of field in the Frame
        frame.add(find); // adding Field in the frame


        replaceLabel = new JLabel("Replace");  //Creating a Label for Replace
        replaceLabel.setFont(new Font("Serif", Font.BOLD, 20)); // setting Font Style and Size for Label
        replaceLabel.setBounds(80,130,150,30); // Giving Label a location in Frame
        frame.add(replaceLabel); // adding Label in Frame


        replace = new JTextField(); // initialized textField here
        replace.setToolTipText("Word to Replace");  // adding a tool tip when cursor is placed o field
        replace.setFont(new Font("Serif", Font.PLAIN, 18)); // setting fonts
        replace.setBounds(165,130,350,32); // adding position of field in the Frame
        frame.add(replace); // adding Field in the frame

        JRadioButton op1=new JRadioButton("FindReplace");

        ButtonGroup bg = new ButtonGroup();
        op1.setBounds(80,290,100,32);

        bg.add(op1);

        frame.add(op1);


        
        start = new JButton("START");
        start.setBounds(450,290,80,32);
        start.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                if(path.getText()==null || path.getText().equals("")){
                    JOptionPane.showMessageDialog(null, "Enter Path First");
                    frame.setVisible(false);
                    new FileSystem();
                }
                fileDirectory = new File(path.getText()+""); //file path obtained from field
                /// Testing method here
                


                if(op1.isSelected()){ // Find and Replace
                    if(find.getText()==null || find.getText().equals("")){
                        JOptionPane.showMessageDialog(null, "Fill the fields first");
                    }
                    else{
                        findWord(fileDirectory);
                        JOptionPane.showMessageDialog(null, "Replaced Successfully");
                    }   

                }
                else if(op2.isSelected()){ // Copy Image
                    if(image.getText()==null || path.getText().equals("")){
                        JOptionPane.showMessageDialog(null, "Fill the fields first");
                    }
                    else{
                        //////////////////////////////////////////////////////////////////////////////////////////////////
                        String filename = fileSelectedViaChooser.getName(); //name of the file that is to be copied obtained here
                        File newFile = new File(filename); // new file object with same name created
                        newFile = new File(fileDirectory.getPath()+"\\"+newFile.getPath()); // adding the destination address of file
                        newFile.mkdir(); // making a new file where the contents should be copied
                        try{ // try catch blocks because IO Files throw exceptions
                            fileCopy(fileSelectedViaChooser, newFile); // fileCopy method passed source and destionation
                        }catch(Exception exp){
                            exp.printStackTrace();
                        }
                    }   
                }

                else if(!(op1.isSelected() && op2.isSelected() && op3.isSelected() && op4.isSelected())){
                    JOptionPane.showMessageDialog(null, "Please Choose an Action First");
                }
                


               
            } // end of actionPerformed
        });
        frame.add(start);

        frame.setVisible(true); // making the Frame Visible

    }
    public BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException { //method that resizes the Image using graphics 2D
        BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = resizedImage.createGraphics();
        graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
        graphics2D.dispose();
        return resizedImage;
    }
    public void fileCopy(File source, File destination)throws IOException{ // image copying method
                URL imageURL = source.toURL(); //source's URL obtained because it's a picture
                BufferedImage bi = ImageIO.read(imageURL); // image read from URL
                //ImageIO.write(bi, "png", destination); // image copied as it is


                //Resizing the Image; 
                BufferedImage img1 = resizeImage(bi, 72,72);
                BufferedImage img2 = resizeImage(bi, 48,48);
                BufferedImage img3 = resizeImage(bi, 96,96);
                BufferedImage img4 = resizeImage(bi, 144,144);
                BufferedImage img5 = resizeImage(bi, 192,192);


                //Copying resized files twice as name ic_launcher.png and ic_launcher_round.png 
                //Constatn Directories
                File PATH1 = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-hdpi\\ic_launcher.png");
                File PATH1a = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-hdpi\\ic_launcher_round.png");
                
                File PATH2 = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-mdpi\\ic_launcher.png");
                File PATH2a = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-mdpi\\ic_launcher_round.png");
                
                File PATH3 = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-xhdpi\\ic_launcher.png");
                File PATH3a = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-xhdpi\\ic_launcher_round.png");
                
                File PATH4 = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-xxhdpi\\ic_launcher.png");
                File PATH4a = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-xxhdpi\\ic_launcher_round.png");
                
                File PATH5 = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-xxxhdpi\\ic_launcher.png");
                File PATH5a = new File(path.getText()+"\\app\\src\\main\\res\\mipmap-xxxhdpi\\ic_launcher_round.png");
        


                ImageIO.write(img1, "png", PATH1);
                ImageIO.write(img2, "png", PATH2);
                ImageIO.write(img3, "png", PATH3);
                ImageIO.write(img4, "png", PATH4);
                ImageIO.write(img5, "png", PATH5);

                ImageIO.write(img1, "png", PATH1a);
                ImageIO.write(img2, "png", PATH2a);
                ImageIO.write(img3, "png", PATH3a);
                ImageIO.write(img4, "png", PATH4a);
                ImageIO.write(img5, "png", PATH5a);
                JOptionPane.showMessageDialog(null,"Copied! Successfully"); // Message Printed

    }
    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);  
       } 


        //showFiles(dir.listFiles());

    }


    
 /*   private void findAndReplace(String currentFile) {

        System.out.println("Current file: " + currentFile);

        BufferedReader reader = null;
        BufferedWriter writer = null;
        String content = "";
        try {
            reader = new BufferedReader(new FileReader(currentFile));

            String line = reader.readLine();

            while (line != null) {
                content += line + System.lineSeparator();
                line = reader.readLine();
            }


            String updatedContent = content.replaceAll(findWord, replaceWord);

            writer = new BufferedWriter(new FileWriter(currentFile));
            writer.write(updatedContent);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                if (reader != null) {
                    reader.close();
                }
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
*/
     

    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();
            }
        }
    }

     


  /*  private static String getExtension(String filename) { // method that gets extension from a file
        if (filename == null) {
            return null;
        }

            String extension = ""; 
            int i = filename.lastIndexOf('.'); 
            if (i > 0) { 
                extension = filename.substring(i + 1);
                return extension; 
            } 
            return "";  
  
           
    }*/
    public static void main(String[] args){
        new FileSystem();
        //System.out.println(getExtension("MainActivity.txt"));
        
            
    }
}

This code is working perfectly, but it takes too long. Is there any way that I can improve the performance of this program ?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ How long is too long? Based on what dataset size? (# folders, #files, #characters/file, total MB) \$\endgroup\$ – AJNeufeld Jan 21 at 15:09
  • \$\begingroup\$ Get yourself a profiler tool and have it show you the hotspot (the place where your program spends 90% of time). It might be the line oldContent = oldContent + line + System.lineSeparator(); If so, use a StringBuilder instead of a String for oldContent. \$\endgroup\$ – Ralf Kleberhoff Jan 22 at 13:57
  • 3
    \$\begingroup\$ Welcome to CodeReview@SE. Advice for posting: heed the help like How do I ask a Good Question? Proof-read. Advice for presenting code: check layout of presentation, copy from there into fresh environment and check it still compiles/works. Don't write, never present undocumented/uncommented code. \$\endgroup\$ – greybeard Feb 14 at 8:20
  • \$\begingroup\$ The code should be production ready code, and should not contain commented out functions. \$\endgroup\$ – pacmaninbw Feb 14 at 14:50