Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Java - Updating a specific line of a file

Options
  • 30-12-2012 6:15pm
    #1
    Registered Users Posts: 52 ✭✭


    (TL;DR - Read title!)

    Hey,

    So I'm working on this little project as practice - it's a bank account manager. So far, you can register an account, log in, etc - account details are stored in a .txt file. No problem there.

    I have a text file that shows the user's balance, and want to update their cash amount when they deposit or withdraw cash - this is also stored in a text file, balance.txt. Line number corresponds with their ID number.

    I've tried loads of different ways of doing this, particularly from searching Google, but no luck yet.

    Here's the deposit part of my code, added comments to give a better understanding of what's going on.
    else if(option.toUpperCase().equals("D")){ //Just user option to deposit
    	Scanner input = new Scanner(System.in);
            System.out.println("How much would you like to deposit?");
    	String depositAmount = input.nextLine();
    
    	int amount = Integer.parseInt(depositAmount);
    	String line = balanceList.get(index); /*Index is ID entered in earlier code and balanceList is a list containing balance.txt values.*/
    	int lineValue = Integer.parseInt(line);
    	int balanceAmount = lineValue + amount;
    
    	StringBuilder sb = new StringBuilder();
    	sb.append(balanceAmount);
    	String newBalance = sb.toString();
    			
    	File balanceFile = new File("balances.txt");
    	File tempB = new File("tempB.txt");
    			
    	RandomAccessFile raf = new RandomAccessFile(balanceFile, "r");
    	FileWriter fw = new FileWriter(tempB);  
    	BufferedWriter bw = new BufferedWriter(fw);
    	        
            int lineCount = 0;
    	
            while((lineCount = raf.read()) != -1){
                    lineCount++;
                    
                    if(lineCount == index){
                            bw.write(newBalance);
                            tempB.renameTo(balanceFile);
                    }
            }
    
    	}
    

    There might be some stupid mistake in there, been messing around with a lot of different ways of doing this. Feel free to suggest a completely different method, this is just the last one I tried.

    Thanks, Fergal.

    Edit: My solution: http://www.boards.ie/vbulletin/showpost.php?p=82446336&postcount=17


Comments

  • Registered Users Posts: 27,161 ✭✭✭✭GreeBo


    so what bit is the problem...whats not working?
    you might want to flush and close those writers/streams...and I would rename it outside of writing the change to it.

    have you considered writing it as XML, make it easier to parse (traverse with a sax parser for example, or just load it as a dom if its not a large file)


  • Registered Users Posts: 27,161 ✭✭✭✭GreeBo


    another option, store the file in an object and just serialize it to disk (so write the entire file, rather than reading and writing it piece by piece)
    It will be slow if you are traversing the file each time to find the correct line

    you can update the object in parallel and just have 1 thread doing the writing...


  • Registered Users Posts: 52 ✭✭iFergal


    With the current code, it seems to return a blank tempB.txt file and no changes to balances.txt whatsoever.
    As for flushing and closing, usually do that, was messing around with the code before I posted, but I will keep in mind to rename outside.

    I have no experience with XML, but I'll look into it later as well as serialization, saw someone mention that elsewhere but didn't try it yet.

    Thanks.


  • Registered Users Posts: 27,161 ✭✭✭✭GreeBo


    probably you are renaming the file before the content has been flushed from the buffer actually to the file.

    try move the rename outside of all the reading/writing block, it doesnt need to be there (and imo shouldnt be)

    /edit
    or even just add a flush before the rename, you can close afterwards
    at least you will know its working.

    The issue is that if you are only writing a small bit to the stream, it will not fill the buffer and so it wont go to the stream (i.e. the file) until you call close (which automatically calls flush)


  • Registered Users Posts: 52 ✭✭iFergal


    Still made no difference. Put a print statement in my loop/if and apparently it's just that the if statement condition is false - which is something I expected, wasn't quite sure when I wrote it.


  • Advertisement
  • Registered Users Posts: 27,161 ✭✭✭✭GreeBo


    should be

    linecount == line
    I believe?

    it looks like line is the line number that you get from the balance list using "index" as the key


  • Registered Users Posts: 52 ✭✭iFergal


    That would make more sense (well actually lineValue - int), still no luck. What I'm trying to accomplish with the if statement, is that when it reads the lines, once it reaches the line at the number which is equal to the the index (or user ID), to update that line. Or will I have to index all the lines some way?


  • Registered Users Posts: 27,161 ✭✭✭✭GreeBo


    sorry yeah, linevalue

    no you dont need to index them, natural index of line number
    however, does your mapping start at 0 or 1?
    because your linecount is starting at 0...

    have you stepped through it in a debugger?


  • Registered Users Posts: 52 ✭✭iFergal


    0. And no


  • Registered Users Posts: 27,161 ✭✭✭✭GreeBo


    debugger is your friend!

    fastest way to debug a problem :)

    probably over looking something simple or its going down some path (or not!) that you expect


  • Advertisement
  • Registered Users Posts: 52 ✭✭iFergal


    Debugged and it ran the loop without running the if statement several times, much more than the actual amount of lines I have.


  • Banned (with Prison Access) Posts: 1,435 ✭✭✭areyawell


    .


  • Banned (with Prison Access) Posts: 1,435 ✭✭✭areyawell


    Might not be the prettiest way but done it off the top of my head. Obviously I left out a ton of code.

    Int newbalance = $756
    File inputFile = new File("Balances.txt");
    File tempFile = new File("myTempFile.txt");
    
    BufferedReader reader = new BufferedReader(new FileReader(inputFile));
    BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
    
    String lineToUpdate = "Balance";
    String currentLine;
    
    while((currentLine = reader.readLine()) != null) {
    // trim newline when comparing with lineToRemove
    String trimmedLine = currentLine.trim();
    if(trimmedLine.equals(lineToUpdate)) continue{
    if ( trimmedLine.indexOf( linetoUpdate) > -1 ) 
    writer.write("Balance =" +newbalance);
    }
    
    boolean successful = tempFile.renameTo(inputFile);
    }
    

    Ill try and get working your way in the next few mins


  • Closed Accounts Posts: 2,663 ✭✭✭Cork24


    Can u post up all your code and I have a look a it...

    You using arrays or arraylist ?

    In your above code why do you have a string In an int ???


  • Registered Users Posts: 52 ✭✭iFergal


    @areyawell: Wrote "?" to my temp file and did nothing to my original, hmm. (Thanks anyway!)

    @Cork24: Ignore the withdraw part before the deposit part, was messing around, only testing deposit, then will add to withdraw.
    import java.io.*;
    import java.text.*;
    import java.util.*;
    
    public class Account {
    	
    	private static boolean loggedIn;
    	private static Date ts = new Date();
    	private static SimpleDateFormat time =  new SimpleDateFormat("H:mm:ss");
    	private static String formattedDate = time.format(ts);
    	static List<String> count = new ArrayList<String>();
    	static List<String> IDlist = new ArrayList<String>();
    	static List<String> PinList = new ArrayList<String>();
    	static List<String> balanceList = new ArrayList<String>();
    	
    	public static void main(String args[]) throws IOException{
    		System.out.print("Welcome to Bank of Rathmore ATM machine. \n");
    		addToArrayList(count, "I:\\Documents and Settings\\Donal\\Desktop\\jProject\\count.txt");
    		choiceLoop();
    		
    	}
    	
    	public static void choiceLoop() throws IOException{
    		Scanner input0 = new Scanner(System.in);
    		System.out.print("Enter 'R' to register an account, or 'L' to login. \n");
    		String choice = input0.nextLine();
    		
    		if(choice.toUpperCase().equals("R")){
    			register();
    		}
    		else if(choice.toUpperCase().equals("L")){
    			login();
    		}
    		else{
    			System.out.println("Please only enter the specified characters.");
    			choiceLoop();
    		}
    		
    		input0.close();
    	}
    	public static void register() throws IOException{
    		Scanner input2 = new Scanner(System.in);
    		System.out.println("Please enter a 4-didget PIN code: ");
    		String regPin = input2.nextLine();
    		int length = String.valueOf(regPin).length();
    		if(length == 4){
    			
    			
    			PrintWriter pw = new PrintWriter(new FileWriter("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\pin.txt", true));
    			pw.println(regPin);
    			pw.close();
    			
    			String counter = count.get(0);
    			int intcounter = Integer.parseInt(counter);
    			intcounter++;
    			
    			PrintWriter countPW = new PrintWriter(new FileWriter("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\count.txt"));
    			countPW.println(intcounter);
    			countPW.close();
    			
    			PrintWriter idPW = new PrintWriter(new FileWriter("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\details.txt", true));
    			idPW.println(intcounter);
    			idPW.close();
    			
    			PrintWriter balancePW = new PrintWriter(new FileWriter("I:\\Documents and Settings\\Donal\\Desktop\\balance.txt", true));
    			balancePW.println("0");
    			balancePW.close();
    			
    			Formatter cash = new Formatter("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\balances\\" + intcounter + ".txt");
    			cash.format("%s", "0");
    			
    			System.out.println("Thank you for registering. Below are your new account log in details.");
    			System.out.println("Account ID: " +intcounter);
    			System.out.println("PIN Code: " +regPin + "\n\n");
    			cash.close();
    			login();
    		}
    		else{
    			System.out.println("Error: PIN must be 4-didgits long.");
    			register();
    		}
    		
    		input2.close();
    	}
    	
    	public static void login() throws IOException{
    
    		Scanner input1 = new Scanner(System.in);
    		System.out.println("Please enter your unique ID number:");
    		addToArrayList(IDlist, "I:\\Documents and Settings\\Donal\\Desktop\\jProject\\details.txt");
    		try{
    			String inputID = input1.nextLine();
    			if(IDlist.contains(inputID)){
    				addToArrayList(PinList, "I:\\Documents and Settings\\Donal\\Desktop\\jProject\\pin.txt");
    				System.out.println("Please enter your PIN code:");
    				String inputPin = input1.nextLine();
    				int indexID = IDlist.indexOf(inputID);
    				if(PinList.indexOf(inputPin) == indexID){
    					String logInTime = formattedDate;
    					System.out.println("Welcome back. You logged in at: " + logInTime);
    				//	showDetails(indexID);
    					cashUpdate(indexID);
    				}else{
    					System.out.print("Incorrect PIN code. ");
    					login();
    					}
    				}else if(inputID.toUpperCase().equals("R")){
    					register();
    				}
    				else{
    					System.out.print("User ID not found. ");
    					login();
    				}
    			}catch(InputMismatchException e){
    				System.out.print("Please only enter didgits. ");
    				login();
    			}
    		input1.close();
    	}
    	
    	public static void addToArrayList(List<String> al, String filepath) throws IOException {
    	        FileArrayProvider fa = new FileArrayProvider();
    	        String[] lines = fa.readLines(filepath);
    	        for (String line : lines) {
    	        	try{
    	            al.add(line);
    	        	}catch(NumberFormatException e){}
    	        }
    	    }
    	
    	public static void showDetails(int index) throws IOException{
    		addToArrayList(balanceList, "I:\\Documents and Settings\\Donal\\Desktop\\jProject\\balances.txt");
    		System.out.println("Account details for ID " + index + ":");
    		System.out.println("Account Balance: &#8364;" + balanceList.get(index) + "\n");
    	}
    	
    	public static void cashUpdate(int index) throws IOException{
    		Scanner input3 = new Scanner(System.in);
    		System.out.println("Press 'W' to withdraw cash, 'D' to deposit cash, or 'EXIT' to logout and close program.");
    		String option = input3.nextLine();
    		addToArrayList(balanceList, "I:\\Documents and Settings\\Donal\\Desktop\\jProject\\balances.txt");
    
    		if(option.toUpperCase().equals("W")){
    			System.out.println("How much would you like to withdraw?");
    			String withdrawAmount = input3.nextLine();
    			int amount = Integer.parseInt(withdrawAmount);
    			PrintWriter balancePW = new PrintWriter(new FileWriter("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\balance.txt", true));
    	        Scanner sc = new Scanner (new File("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\balance.txt"));
    	        RandomAccessFile raf = new RandomAccessFile("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\balance.txt", "rw");
    	        int lineCount = 0;
    	        while(raf.read() != -1){
    	        	lineCount++;
    	        	System.out.println(lineCount);
    	        }
    	        while  (sc.hasNext() ){
    	            String line = balanceList.get(index);
    	            int lineValue = Integer.parseInt(line);
    	            int balanceAmount = lineValue - amount;
    	            
    				StringBuilder sb = new StringBuilder();
    				sb.append(balanceAmount);
    				String newBalance = sb.toString();
    				if(lineCount == index){
    					balancePW.println(newBalance);
    				}
    	            System.out.println("&#8364;" + amount + " withdrawed from account at " + formattedDate);
    	        }
    			balancePW.close();
    		}
    		else if(option.toUpperCase().equals("D")){
    	        System.out.println("How much would you like to deposit?");
    	    	String depositAmount = input3.nextLine();
    
    	    	int amount = Integer.parseInt(depositAmount);
    	    	String line = balanceList.get(index); /*Index is ID entered in earlier code and balanceList is a list containing balance.txt values.*/
    	    	int lineValue = Integer.parseInt(line);
    	    	int balanceAmount = lineValue + amount;
    
    	    	StringBuilder sb = new StringBuilder();
    	    	sb.append(balanceAmount);
    	    	String newBalance = sb.toString();
    	    			
    	    	File balanceFile = new File("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\balances.txt");
    	    	File tempB = new File("I:\\Documents and Settings\\Donal\\Desktop\\jProject\\tempB.txt");
    	    			
    	    //	RandomAccessFile raf = new RandomAccessFile(balanceFile, "r");
    	    	BufferedReader br = new BufferedReader(new FileReader(balanceFile));
    	    	FileWriter fw = new FileWriter(tempB);  
    	    	BufferedWriter bw = new BufferedWriter(fw);
    	    	
    	    	int nb = 765;
    	    	String lineToUpdate = "Balance";
    	    	String currentLine;
    	    	while((currentLine = br.readLine()) != null){
    		    	String trimmedLine = currentLine.trim();
    		    	if ( trimmedLine.indexOf(lineToUpdate) > -1 ) {
    		    		bw.write(nb);
    		    	}
    	    	}
    
    	        boolean successful = tempB.renameTo(balanceFile);
    	        
    	    	/*       int lineCount = 0;
    	        while((lineCount = raf.read()) != -1){
    	        	lineCount++;
            		
    	        	if(lineCount == lineValue){
    	        		bw.write(newBalance);
    	        		}
    	        	}*/
    	        bw.flush();
    	        br.close();
    	        bw.close();
    		
    			System.out.println("&#8364;" + amount + " added to account at " + formattedDate);
    
    			}else if(option.toUpperCase().equals("EXIT")){
    			System.out.println("System terminated by user.");
    			System.exit(0);
    		}
    	}
    }
    


  • Registered Users Posts: 52 ✭✭iFergal


    Fixed it! Was messing around with my code and found a way to fix it, I'll leave code below. Might be a bit messy, but only thing that worked for me. Thanks for everyone's help though!
    else if(option.toUpperCase().equals("D")){
    	System.out.println("How much would you like to deposit?");
    	String depositAmount = input3.nextLine();
    
    	int amount = Integer.parseInt(depositAmount);
    	String line = balanceList.get(index); /*Index is ID entered in earlier code and balanceList is a list containing balance.txt values.*/
    	int lineValue = Integer.parseInt(line);
    	int balanceAmount = lineValue + amount;
    
    	StringBuilder sb = new StringBuilder();
    	sb.append(balanceAmount);
    	String newBalance = sb.toString();
    	    	
    	File balanceFile = new File("balances.txt");
     	File tempFile = new File("tempB.txt");
    	BufferedReader br = new BufferedReader(new FileReader(balanceFile));
    	BufferedWriter bw = new BufferedWriter(new FileWriter(tempFile, true));
    	    	
    	for(int i = 0; i < index; i++){ //Write lines before line required for updating
    	    bw.write(balanceList.get(i));
    	    bw.newLine();
    	}
    	    	
    	bw.write(newBalance); //Write the updated line value
    	bw.newLine();
    	    	
    	for(int i = index + 1; i < balanceList.size(); i++){ //Write the remaining values after
    	    bw.write(balanceList.get(i));
    	    bw.newLine();
    	}
    	    	
    	bw.flush();
    	br.close();
    	bw.close();
    	    	
    	balanceFile.delete(); //Required in XP for some reason...
    	tempFile.renameTo(balanceFile);
    	        
    	System.out.println("&#8364;" + amount + " added to account at " + formattedDate);
    			
    	Formatter createTemp = new Formatter("tempB.txt"); //Create for next time someone deposits/withdraws.
    	}
    


Advertisement