9 Replies - 1011 Views - Last Post: 07 July 2011 - 07:16 AM Rate Topic: -----

#1 trixt.er  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 41
  • View blog
  • Posts: 395
  • Joined: 28-September 08

Large file and read line

Posted 06 July 2011 - 11:36 AM

Hey guys. I'm having some trouble with a text editor I have thrown together. I'm using a buffered reader with read line to
read in an entire file of text. The file is roughly 11 mb. It's taking a while to read it in. Any suggestions on optimizations?
My user name has been blocked out of the file path.

Below is the code.
import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
public class TextEditorRevised
{
	private boolean flag = false;
	private boolean changed = false;
	private boolean saved = false;
	private JFrame frame;
	private FileDialog fileDialog;
	private MenuBar menuBar;
	private JPanel p;
	private String fileName = "Untitled"; // TODO: remove after testing
	private String filePath = "/Users/#########/Documents/workspace/TheLookingGlass/fileData.txt"; // TODO: remove after testing
	// private String filePath = "/Users/#########/Desktop/main.cpp";
	private String infoMessage;
	private String findStr, findInStr;
	private int startIndex, endIndex;
	private int clicked;
	private final String appName = "Text Editor";
	private TextArea txtArea;
	private JToolBar toolBar;
	private JButton find;


	public TextEditorRevised() throws IOException
	{		
		frame = new JFrame();
		frame.setSize(838,527);//838 X 527
		frame.setLocation(200,100);//set initial location on the screen
		frame.setTitle("Search Results");//set title
		frame.setFont(new Font("Calibri",Font.BOLD,12));

		menuBar = new MenuBar();

		/*Find button*/
		find = new JButton("Find");		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		find.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				findInStr = txtArea.getText();
				clicked = 0;
				FindDialogBox fdb = new FindDialogBox();
			}
		});
		/*Adding Find button to Frame*/
		frame.add(find);
		frame.setMenuBar(menuBar);

		p = new JPanel();
		p.setLayout(new BorderLayout());
		txtArea = new TextArea();
		txtArea.setFont(new Font("Calibri",Font.PLAIN,12));
		txtArea.addTextListener(new TextListener()
		{
			public void textValueChanged(TextEvent e)
			{
				saved = false;
				changed = true;
			}
		});
	    FileInputStream inStream = new FileInputStream(filePath);
	    DataInputStream inFile = new DataInputStream(inStream);
        BufferedReader inBr = new BufferedReader(new InputStreamReader(inFile));
        String line = "";
        String totalLines = "";
        while ((line = inBr.readLine()) != null){ // <--- VERY SLOW!
        	totalLines += (line + "\n");
        	System.out.println(line);
        }
        txtArea.setText(totalLines);
        
        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));        
        p.add(find, JPanel.LEFT_ALIGNMENT);
		p.add(txtArea,"Center");
		

		frame.add(p);
		frame.setVisible(true);
	}

	public void saveAsFile()
	{
		fileDialog = new FileDialog(frame,"Open",FileDialog.SAVE);
		fileDialog.setVisible(true);
		fileName = fileDialog.getFile();
		filePath = fileDialog.getDirectory();
		File f;
		FileOutputStream fos;
		BufferedOutputStream bos;
		frame.setTitle(fileName+" - "+appName);
		try
		{
			f = new File(filePath+fileName);
			fos = new FileOutputStream(f);
			bos = new BufferedOutputStream(fos);
			String str=txtArea.getText();
			char []ch = str.toCharArray();
			for(int i=0;i<ch.length;i++)
			{
				bos.write(ch[i]);
			}	
			bos.close();
			fos.close();
			saved = true;
		}
		catch(IOException io)
		{
			System.out.println(io.getMessage());
		}
	}

	private class ConfirmDialogBox
	{
		//Frame frCDBox;
		Dialog frCDBox;
		Button btYes,btNo,btCancel;
		Label lbWarning,lbConfirm;

		public ConfirmDialogBox()
		{
			frCDBox = new Dialog(frame);
			frCDBox.setSize(265,120);
			frCDBox.setLocation(400,300);
			frCDBox.setFont(new Font("Calibri",Font.BOLD,12));
			frCDBox.setTitle("Confirm");
			frCDBox.setBackground(new Color(236,236,236));
			frCDBox.setLayout(new GridBagLayout());
			GridBagConstraints gbc = new GridBagConstraints();
			lbWarning = new Label("The text in the "+fileName+" file has changed");
			lbConfirm = new Label("Do you want to save the changes?");
			btYes = new Button("Yes");
			btYes.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					frCDBox.setVisible(false);
					frCDBox.dispose();
					saveAsFile();
					txtArea.setText("");
					fileName = "Untitled";
					frame.setTitle(fileName+" - "+appName);
				}
			});
			btNo = new Button("No");
			btNo.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					frCDBox.setVisible(false);
					frCDBox.dispose();
					txtArea.setText("");
					fileName = "Untitled";
					frame.setTitle(fileName+" - "+appName);
				}
			});
			btCancel = new Button("Cancel");
			btCancel.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					frCDBox.setVisible(false);
					frCDBox.dispose();
				}
			});
			gbc.gridx = 0;
			gbc.gridy = 0;
			gbc.gridwidth = 3;
			gbc.anchor = GridBagConstraints.WEST;
			Insets inset = new Insets(4,4,0,8);
			gbc.insets = inset;
			frCDBox.add(lbWarning,gbc);//(0,0)
			gbc.gridx = 0;
			gbc.gridy = 1;
			frCDBox.add(lbConfirm,gbc);//(0,1)
			gbc.gridx = 0;
			gbc.gridy = 2;
			gbc.gridwidth=1;
			frCDBox.add(btYes,gbc);//(0,2)
			gbc.gridx = 1;
			gbc.gridy = 2;
			frCDBox.add(btNo,gbc);//(1,2)
			gbc.gridx = 2;
			gbc.gridy = 2;
			frCDBox.add(btCancel,gbc);//(2,2)
			frCDBox.setVisible(true);

		}
	}

	private class FindDialogBox
	{
		//Frame frFind;
		Dialog frFind;
		Button btFind,btClose;
		Label lbFind;
		TextField tfFind;
		Checkbox cbMatchCase;


		public FindDialogBox()
		{
			frFind = new Dialog(frame);
			frFind.setSize(300,100);
			frFind.setLocation(700,150);
			frFind.setTitle("Find");
			frFind.setBackground(new Color(95, 158, 160)); // Burlywood see -> http://www.jafar.com/java/csel/index.html
			frFind.setLayout(new GridBagLayout());
			GridBagConstraints gbcFind = new GridBagConstraints();
			lbFind = new Label("Find");
			tfFind = new TextField(20);
			tfFind.addTextListener(new TextListener()
			{
				public void textValueChanged(TextEvent e)
				{
					clicked = 0;	
				}
			});
			btFind = new Button("Find");
			btFind.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e) 
				{
					if(tfFind.getText()!="")
					{
						findStr = tfFind.getText();
						
						startIndex=findInStr.indexOf(findStr,clicked);
						
						if(startIndex!=-1)
						{
							endIndex = findStr.length();
							
							//frFind.toBack();
							//frame.setFocusable(true);
							frame.requestFocus();	
							txtArea.select(startIndex,startIndex+endIndex);
							// txtArea.setSelectedTextColor(Color.yellow);

							clicked = startIndex +1;
						}
						else
						{
							infoMessage = "Cannot find " + "\""+findStr+"\""; 
							MessageBox msg = new MessageBox();
						}	
					}
				}
			});
			btClose = new Button("Close");
			btClose.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					//tfFind.setText() = "";
					clicked = 0;
					findInStr ="";
					findStr="";
					startIndex = 0;
					endIndex = 0;
					frFind.setVisible(false);
					frFind.dispose();
				}
			});
			cbMatchCase = new Checkbox("Match Case");
			gbcFind.gridx = 0;
			gbcFind.gridy = 0;
			gbcFind.ipadx = 2;
			gbcFind.ipady = 2;
			Insets insetFind = new Insets(4,4,0,8);
			gbcFind.insets = insetFind;
			gbcFind.anchor = GridBagConstraints.WEST;
			frFind.add(lbFind,gbcFind);
			gbcFind.gridx = 1;
			gbcFind.gridy = 0;
			gbcFind.gridwidth=3;
			frFind.add(tfFind,gbcFind);
			gbcFind.gridx = 0;
			gbcFind.gridy =1;
			gbcFind.gridwidth=1;
			frFind.add(cbMatchCase,gbcFind);
			gbcFind.gridx = 1;
			gbcFind.gridy = 1;
			frFind.add(btFind,gbcFind);
			gbcFind.gridx = 2;
			gbcFind.gridy = 1;
			frFind.add(btClose,gbcFind);
			frFind.setVisible(true);	
		}
	}

	class MessageBox
	{
		//Frame frMsg;
		Dialog frMsg;
		Label lbMsg;
		Button btMsgOk;

		public MessageBox()
		{
			frMsg = new Dialog(frame);
			frMsg.setSize(180,100);
			frMsg.setLocation(500,300);
			frMsg.setTitle("Text Editor");
			frMsg.setBackground(new Color(189, 183, 107)); // DarkKhaki see -> http://www.jafar.com/java/csel/index.html
			frMsg.setFont(new Font("Calibri",Font.BOLD,12));
			frMsg.setLayout(new GridBagLayout());
			GridBagConstraints gbcMsg = new GridBagConstraints();
			lbMsg = new Label(infoMessage);
			gbcMsg.gridx = 0;
			gbcMsg.gridy = 0;
			gbcMsg.ipadx = 2;
			gbcMsg.ipady = 2;
			frMsg.add(lbMsg,gbcMsg);
			btMsgOk = new Button("Ok");
			btMsgOk.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					frMsg.setVisible(false);
					frMsg.dispose();
				}
			});
			gbcMsg.gridx = 0;
			gbcMsg.gridy = 1;
			gbcMsg.ipadx = 2;
			gbcMsg.ipady = 2;
			frMsg.add(btMsgOk,gbcMsg);
			frMsg.setVisible(true);
		}
	}

	class FindReplaceDialogBox
	{
		//Frame frFReplace;
		Dialog frFReplace;
		Button btFRFindNext, btFRClose;
		Label lbFRFind,lbFRReplace;
		TextField tfFRFind, tfFRReplace;

		public FindReplaceDialogBox()
		{
			frFReplace = new Dialog(frame);
			frFReplace.setSize(330,130);
			frFReplace.setLocation(500,300);
			frFReplace.setTitle("Find and Replace");
			frFReplace.setBackground(new Color(236,236,236));
			frFReplace.setFont(new Font("Calibri",Font.BOLD,12));
			frFReplace.setLayout(new GridBagLayout());
			GridBagConstraints gbcFR = new GridBagConstraints();
			gbcFR.gridx = 0;
			gbcFR.gridy = 0;
			gbcFR.gridwidth = 1;
			gbcFR.anchor = GridBagConstraints.WEST;
			Insets insetFRReplace = new Insets(4,4,0,8);
			gbcFR.insets = insetFRReplace;
			lbFRFind = new Label("Find");
			frFReplace.add(lbFRFind,gbcFR);
			gbcFR.gridx = 1;
			gbcFR.gridy = 0;
			gbcFR.gridwidth = 3;
			gbcFR.anchor = GridBagConstraints.WEST;
			tfFRFind = new TextField(26);
			frFReplace.add(tfFRFind,gbcFR);
			tfFRFind.addTextListener(new TextListener()
			{
				public void textValueChanged(TextEvent e)
				{
					clicked = 0;
				}
			});
			gbcFR.gridx = 0;
			gbcFR.gridy = 1;
			gbcFR.gridwidth = 1;
			gbcFR.anchor = GridBagConstraints.WEST;
			lbFRReplace = new Label("Replace With");frFReplace.add(lbFRReplace,gbcFR);
			gbcFR.gridx = 1;
			gbcFR.gridy = 1;
			gbcFR.gridwidth = 3;
			gbcFR.anchor = GridBagConstraints.WEST;
			tfFRReplace = new TextField(26);frFReplace.add(tfFRReplace,gbcFR);
			gbcFR.gridx = 0;
			gbcFR.gridy = 2;
			gbcFR.gridwidth = 1;
			gbcFR.anchor = GridBagConstraints.WEST;
			btFRFindNext = new Button("Find Next");frFReplace.add(btFRFindNext,gbcFR);
			btFRFindNext.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					if(tfFRFind.getText()!="")
					{
						findStr = tfFRFind.getText();
						//System.out.println(findStr);
						startIndex=findInStr.indexOf(findStr,clicked);
						//System.out.println(startIndex);
						if(startIndex!=-1)
						{
							endIndex = findStr.length();
							//System.out.println(endIndex);
							txtArea.select(startIndex,startIndex+endIndex);
							clicked = startIndex +1;
							flag=true;
						}
						else
						{
							infoMessage = "Cannot find " + "\""+findStr+"\""; 
							MessageBox msg = new MessageBox();
						}	
					}
				}
			});
			gbcFR.gridx = 1;
			gbcFR.gridy = 2;
			gbcFR.gridwidth = 1;
			gbcFR.anchor = GridBagConstraints.WEST;

			gbcFR.gridx = 2;
			gbcFR.gridy = 2;
			gbcFR.gridwidth = 1;
			gbcFR.anchor = GridBagConstraints.WEST;

			gbcFR.gridx = 3;
			gbcFR.gridy = 2;
			gbcFR.gridwidth = 1;
		}
	}
	public static void main(String[] args){
		try {
			new TextEditorRevised(); // linked invocation
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
}



Is This A Good Question/Topic? 0
  • +

Replies To: Large file and read line

#2 MATTtheSEAHAWK  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 119
  • View blog
  • Posts: 743
  • Joined: 11-September 10

Re: Large file and read line

Posted 06 July 2011 - 12:29 PM

I'm not sure how well this would work but I use the RandomAccessFile class a lot and what I would do is this:

byte[] byteArray = new byte[randomAccessFileObject.length()]; //create a byte array size of the file
randomAccessFileObject.readFully(byteArray); //read the whole file into the byte array
String text = new String(byteArray); //create a new string from the bytes


I haven't tested that so no guarantees on how it will work.

On another note why are you calling setText instead of naming the frame in the constructor on line 38?
Was This Post Helpful? 2
  • +
  • -

#3 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 994
  • View blog
  • Posts: 2,208
  • Joined: 05-April 11

Re: Large file and read line

Posted 06 July 2011 - 01:14 PM

I believe it is because of the System.out.println( line ) that is takes so long.

Try and remove the System.out.println( line ); :)

EDIT: Also I don't like all the hard coded numbers you are using like frFReplace.setLocation(500,300);.

This post has been edited by CasiOo: 06 July 2011 - 01:18 PM

Was This Post Helpful? 0
  • +
  • -

#4 trixt.er  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 41
  • View blog
  • Posts: 395
  • Joined: 28-September 08

Re: Large file and read line

Posted 06 July 2011 - 02:31 PM

View PostCasiOo, on 06 July 2011 - 02:14 PM, said:

I believe it is because of the System.out.println( line ) that is takes so long.

Try and remove the System.out.println( line ); :)

EDIT: Also I don't like all the hard coded numbers you are using like frFReplace.setLocation(500,300);.

Not really.

View PostMATTtheSEAHAWK, on 06 July 2011 - 01:29 PM, said:

I'm not sure how well this would work but I use the RandomAccessFile class a lot and what I would do is this:

byte[] byteArray = new byte[randomAccessFileObject.length()]; //create a byte array size of the file
randomAccessFileObject.readFully(byteArray); //read the whole file into the byte array
String text = new String(byteArray); //create a new string from the bytes


I haven't tested that so no guarantees on how it will work.

On another note why are you calling setText instead of naming the frame in the constructor on line 38?


Thank you so much. Wow. This is very efficient. I set it to read only. So... are there any security risks or issues associated with this method?
Was This Post Helpful? 0
  • +
  • -

#5 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2113
  • View blog
  • Posts: 8,802
  • Joined: 20-September 08

Re: Large file and read line

Posted 06 July 2011 - 02:58 PM

Use http://download.orac...(java.io.Reader, java.lang.Object)
Was This Post Helpful? 1
  • +
  • -

#6 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 994
  • View blog
  • Posts: 2,208
  • Joined: 05-April 11

Re: Large file and read line

Posted 06 July 2011 - 03:39 PM

View Posttrixt.er, on 06 July 2011 - 02:31 PM, said:

View PostCasiOo, on 06 July 2011 - 02:14 PM, said:

I believe it is because of the System.out.println( line ) that is takes so long.

Try and remove the System.out.println( line ); :)

EDIT: Also I don't like all the hard coded numbers you are using like frFReplace.setLocation(500,300);.

Not really.

View PostMATTtheSEAHAWK, on 06 July 2011 - 01:29 PM, said:

I'm not sure how well this would work but I use the RandomAccessFile class a lot and what I would do is this:

byte[] byteArray = new byte[randomAccessFileObject.length()]; //create a byte array size of the file
randomAccessFileObject.readFully(byteArray); //read the whole file into the byte array
String text = new String(byteArray); //create a new string from the bytes


I haven't tested that so no guarantees on how it will work.

On another note why are you calling setText instead of naming the frame in the constructor on line 38?


Thank you so much. Wow. This is very efficient. I set it to read only. So... are there any security risks or issues associated with this method?


What is really causing it is that you are making a new String object every time with the content of the old String.
Instead use a StringBuffer.

Also the System.out.println(); will give you many seconds delay in a 10mb file the way you did it :)

        BufferedReader inBr = new BufferedReader(new FileReader(filePath));
        String line = "";
        long timeBefore = System.currentTimeMillis();
        StringBuffer totalLines = new StringBuffer();
        while ( inBr.ready()){ // <--- VERY SLOW!
        	line = inBr.readLine();
        	totalLines.append( line );
//        	System.out.println(line);
        }
        System.out.println( "Time it took: " + (System.currentTimeMillis() - timeBefore) );
        txtArea.setText(totalLines.toString());



Time it took without system.out.println(): 73ms
Time it took with: 2463ms
tested with 4,1mb file
Was This Post Helpful? 0
  • +
  • -

#7 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2113
  • View blog
  • Posts: 8,802
  • Joined: 20-September 08

Re: Large file and read line

Posted 06 July 2011 - 03:43 PM

That link didn't work sorry. Try this
Was This Post Helpful? 0
  • +
  • -

#8 nick2price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 559
  • View blog
  • Posts: 2,826
  • Joined: 23-November 07

Re: Large file and read line

Posted 06 July 2011 - 03:54 PM

The following way makes sure the file is never read into memory, therefore should theoritcally allow for a quicker execution.
import java.util.*;
import java.io.*;
 
public class Test implements Iterable<String>
{
    private BufferedReader myReader;
 
    public Test(String myFile) throws Exception
    {
	myReader = new BufferedReader(new FileReader(myFile));
    }
 
    public void Close()
    {
	try{
	    myReader.close();
	}
	catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public Iterator<String> iterator()
    {
	return new MyIterator();
    }
 
    private class MyIterator implements Iterator<String>
    {
	private String currentLine;
 
	public boolean hasNext()
	{
	    try{
		currentLine = myReader.readLine();
	    }
	    catch (Exception e){
		currentLine = null;
		e.printStackTrace();
	    }
 
	    return currentLine != null;
	}
 
	public String next()
	{
	    return currentLine;
	}
 
	public void remove(){
	}
    }
}


Just use it like
Test file = new Test("test.txt");
 
for (String line : file){
    System.out.println(line);
}


Additionally, doing it as above makes things more OO which is rather nice.
Was This Post Helpful? 0
  • +
  • -

#9 MATTtheSEAHAWK  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 119
  • View blog
  • Posts: 743
  • Joined: 11-September 10

Re: Large file and read line

Posted 07 July 2011 - 06:18 AM

View Posttrixt.er, on 06 July 2011 - 05:31 PM, said:

View PostCasiOo, on 06 July 2011 - 02:14 PM, said:

I believe it is because of the System.out.println( line ) that is takes so long.

Try and remove the System.out.println( line ); :)

EDIT: Also I don't like all the hard coded numbers you are using like frFReplace.setLocation(500,300);.

Not really.

View PostMATTtheSEAHAWK, on 06 July 2011 - 01:29 PM, said:

I'm not sure how well this would work but I use the RandomAccessFile class a lot and what I would do is this:

byte[] byteArray = new byte[randomAccessFileObject.length()]; //create a byte array size of the file
randomAccessFileObject.readFully(byteArray); //read the whole file into the byte array
String text = new String(byteArray); //create a new string from the bytes


I haven't tested that so no guarantees on how it will work.

On another note why are you calling setText instead of naming the frame in the constructor on line 38?


Thank you so much. Wow. This is very efficient. I set it to read only. So... are there any security risks or issues associated with this method?


No, there are no security risks as far as I know and I googled around for a minute and couldn't find anything either.
Was This Post Helpful? 0
  • +
  • -

#10 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2113
  • View blog
  • Posts: 8,802
  • Joined: 20-September 08

Re: Large file and read line

Posted 07 July 2011 - 07:16 AM

There is already a dedicated method (the link to which i posted) in JTextComponent to fill itself from a file
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1