As was foretold, we've added advertisements to the forums! If you have questions, or if you encounter any bugs, please visit this thread: https://forums.penny-arcade.com/discussion/240191/forum-advertisement-faq-and-reports-thread/
Options

Java Question

samsam7samsam7 Registered User regular
edited February 2010 in Help / Advice Forum
Ok I'm about ready to pull my hair out trying to figure this out:

I'm trying to make a program that scans files line by line, and decides what is an identifier, int, operator etc.

So I'm starting simple and just trying to read one line on an existing file (test.txt), print what it sees, and also output to a new file that the program creates. Here's my code for just reading and printing, I'm using the latest Eclipse to work in.
import java.util.*;
import java.io.*;

public class MyScanner {
	
	public static void main(String[] args) {
	
	String message;
	
	File file = new File("test.txt");
	
	Scanner fileScan = new Scanner (file);
			
	while (fileScan.hasNext())
	{
		message = fileScan.nextLine();
		System.out.println ("Message: " + message);
	}
}
}

However I keep getting a FileNotFoundException at the line where I make the new Scanner. I've tried putting test.txt in every folder in my workspace folder and I keep getting the same thing. So I tried to make a new file to see where its made:
	String message = "AOK";
		
	      File f;
	      f=new File("myfile.txt");
	      if(!f.exists()){
	      f.createNewFile();
	      }
	      
	      if(f.exists()){
	    	  System.out.println (message);
	      }
Now I get an IOException on the line where I create a new file. I also get an invalid escape sequence when I try to write out the entire path.

Anyone know what's going on?

EDIT: Breakthrough! A try/catch statement is used in some online examples (but not in my textbook) so I tried it and now everything works. New code:
import java.util.*;
import java.io.*;

public class MyScanner {
	
	public static void main(String[] args) {
	
//Make new file

		String message = "AOK";
		try{
	      File f;
	      f=new File("myfile.txt");
	      if(!f.exists()){
	      f.createNewFile();
	      }
	      
	      if(f.exists()){
	    	  System.out.println (message);
	      }
		}catch(IOException e){}
		
//Read existing file

	String message2;
	try{
	File file = new File("test.txt");
	
	Scanner fileScan = new Scanner (file);
			
	while (fileScan.hasNext())
	{
		message2 = fileScan.nextLine();
		System.out.println ("Message: " + message2);
	}
	}catch(FileNotFoundException d){}
}
}

So now finally, I would like to know, why did try/catch work? What is it doing behind the scenes, and what is an IOException? Also, changing the catch from FileNotFoundException to IOException still works, so I guess that part in the catch line didn't even matter.

samsam7 on

Posts

  • Options
    soxboxsoxbox Registered User regular
    edited February 2010
    The errors you were getting from your first attempt at the code were compilation errors. The constructor of Scanner can potentially throw a FileNotFoundException - since that is not a RuntimeException, you need to have that handled in your code, either by catching it or throwing it in your method signature.

    The above advice may make no sense to you. If it doesn't, you should go back to chapter one of whatever text book you're using and running examples from there (or better yet, throw away whatever crappy textbook you've likely been assigned and go and read "thinking in java"), because you've missed some pretty fundamental details.

    soxbox on
  • Options
    KlorgnumKlorgnum Registered User regular
    edited February 2010
    FileNotFoundException is a subclass of IOException, which is why they both work in this situation.
    An exception is just an object that is created in response to an error in some function. The exception contains information about the error. A Try/Catch statement lets you Try a piece of code, and if it fails it will Catch the exception you have specified*. You can then do things like System.out.println(e.toString()); to find out what the error was.

    Also, if you're going to post a lot of code, you should use [code] tags. They'll preserve your formatting and make things easier to read.

    Here's the JavaDoc for the Exception base class.
    Java is incredibly well documented, and you should have the docs bookmarked if you don't already.

    Hope this helps.

    *If you want to catch all exceptions, just catch Exception. It's the base class for all other exception classes, so it works with any of them. If you want to catch specific exceptions only, you need to use the right type.

    Klorgnum on
  • Options
    TejsTejs Registered User regular
    edited February 2010
    It's been a while since I last did Java, but don't you need to specifically put in the path name to the file? Unless you stick the file in the folder where your executable is running, it doesn't know where the file exists (or where to put it) which is causing the FileNotFound or IOException.

    Also, a very good practice to consider is to never make empty catch blocks. That is effectively known as a try-swallow, because you are just suppressing the runtime exception. You should be able to breakpoint the logic in your catch statements and inspect the exceptions that were generated to see what the full problem is. In your case, you need to either terminate the program or output an error message. Exceptions are problems that are generated from your code at runtime.

    If you did something like:
    int myVariable = 0;
    
    int anotherVariable = 10 / myVariable;
    

    That's dividing by zero and the JVM should generate an exception for that. When programming, you need to think about how your program could fail (in addition to the way you want it to go), and then wrap those segments with try/catch blocks to make sure your program is more stable. For example, when opening a new file, there is an implicit understanding that the hard drive will be available. That's why things such as IoExceptions and FileNotFoundExceptions can be generated when working with files.

    As for the escape syntax, I'm imagining you did something like "C:\testfile.txt" right? The '\' character is a special escape character from the C(++) days. You need to 'escape' the '\' character to say to use that, because right now the string is:

    [0] = 'C'
    [1] = ':'
    [2] = '\t' (Tab)
    [3] = 'e' etc

    Do something like "C:\\testfile.txt" and you get:

    [0] = 'C'
    [1] = ':'
    [2] = '\\' (backslash)
    [3] = 't'
    [4] = 'e' etc

    Tejs on
  • Options
    RhinoRhino TheRhinLOL Registered User regular
    edited February 2010
    import java.io.File;
    import java.util.Scanner;
    
    public class Test {
    
    	private static Scanner fileScan;
    
    	public static void main(String[] args) {
    
    		String message;
    
    		File file = new File("test.txt");
    
    		try {
    			fileScan = new Scanner(file);
    		} catch (Exception e) {
    			System.out.println("Something went wrong: " + e.getMessage());
    			e.printStackTrace();
    			System.exit(-1);
    		}
    
    		while (fileScan.hasNext()) {
    			message = fileScan.nextLine();
    			System.out.println("Message: " + message);
    		}
    	}
    }
    


    Read up on "Exceptions": http://java.sun.com/docs/books/tutorial/essential/exceptions/

    Rhino on
    93mb4.jpg
  • Options
    RhinoRhino TheRhinLOL Registered User regular
    edited February 2010
    Tejs wrote: »
    It's been a while since I last did Java, but don't you need to specifically put in the path name to the file? Unless you stick the file in the folder where your executable is running, it doesn't know where the file exists (or where to put it) which is causing the FileNotFound or IOException.

    It's relative to the current working directory. Inside a jar, or file system.

    If you have
    C:\project\test\test.txt

    and start your program in C:\project\test then you can just do "test.txt"

    also, use the forward slash if you need a directory; works on all systems. As in:

    "MyDataFolder/test.txt"

    You can give it the full path, but this is bad practice since if you run it as an applet/webstart or from jar it can get confused. The full path in this case would be "C:/project/test/test.txt"

    Rhino on
    93mb4.jpg
  • Options
    samsam7samsam7 Registered User regular
    edited February 2010
    Thanks for the help guys. Klorgnum, I didn't know FileNotFoundException was a subclass of IOException, totally makes sense now. Tejs, thanks for explaining what was going on with the escape syntax. I've done a lot more C++ than Java, and I've never had to catch anything when reading/writing files, so having to take measures in my code for it was kinda new.

    Also, just so I got this down right, I have to account for exceptions in Java no matter what (even when things are in the proper place)? In other words, the exception is always thrown? I ask this because the location I was able to read and generate files was a location I had tried before when I was having problems and received the FileNotFoundException. I always thought exceptions could only happen when something went wrong during compiletime/runtime, not as a precaution.

    samsam7 on
  • Options
    GoetterdaemmerungGoetterdaemmerung Registered User regular
    edited February 2010
    samsam7 wrote: »
    Also, just so I got this down right, I have to account for exceptions in Java no matter what (even when things are in the proper place)? In other words, the exception is always thrown? I ask this because the location I was able to read and generate files was a location I had tried and received the FileNotFoundException. I always thought exceptions could only happen when something went wrong during compiletime/runtime.

    You have to 'account for' (also called handle) exceptions whenever you use a method that throws an exception. If you look at the spec for Scanner's constructor, you'll find it tells you that it "throws FileNotFoundException". If you look at the actual source code for Scanner's constructor, you'll see that the method starts with something like "public Scanner(File f) throws FileNotFoundException { ... ".

    As someone mentioned, you can handle exceptions in two ways: you can surround calls to exception-throwing methods with try/catch blocks, or you can throw the exception yourself (i.e., hot-potato it to whatever is calling *your* method). For "public static void main(String[] args)", you can simply make it "public static void main(String[] args) throws Exception" to tell Java that, should your program fail to handle any exceptions, it should just kill the program -- which is what the JVM will do if your main method actually throws an exception while running.

    Goetterdaemmerung on
  • Options
    SkyCaptainSkyCaptain IndianaRegistered User regular
    edited February 2010
    Also, use (code)(/code) on the forums around your code. Makes it easier to read. =) Just replace the parantheses with square brackets.

    SkyCaptain on
    The RPG Bestiary - Dangerous foes and legendary monsters for D&D 4th Edition
  • Options
    samsam7samsam7 Registered User regular
    edited February 2010
    Goetterdaemmerung, I just realized that so many of the Java methods I've used before in basic programming didn't throw anything so it just went unnoticed to me for a long time. So dealing specifically with the scanner class, why is it that hasnext() throws IllegalStateException, but I don't need to handle it? Rhino's code has an example of that.

    Edit: Is it because it's a runtime exception, wheres filenotfoundexception was a compiletime exception?

    samsam7 on
  • Options
    LewishamLewisham Registered User regular
    edited February 2010
    Yes, runtime exceptions are unchecked.

    This shouldn't mean you shouldn't check it. With file handling, you really, really should because I/O is inherently dangerous as it relies on user input. The user could give you the wrong file name, the file itself could be corrupted to all hell, all sorts of nastiness.

    Fun fact: It's not a Java Virtual Machine thing that causes you to handle checked exceptions, but javac. That's why Scala and Clojure and all those fun things don't need you to handle them.

    Lewisham on
  • Options
    TavataarTavataar Registered User regular
    edited February 2010
    I am a little surprised that Eclipse did not catch this for you.

    Normally when you call a method that throws some sort of Exception, Eclipse will catch that as a Compile Time Error, and force you to surround it with a try/catch before allowing you to run it.

    Did you get a red squiggly line or not?

    Tavataar on
    -Tavataar
  • Options
    samsam7samsam7 Registered User regular
    edited February 2010
    Nope, no red squiggly lines. Eclipse was showing no errors until I tried compiling and running. Maybe I had some setting checked or something.

    Anyhow, the concepts definitely make more sense now. I'm a computer science major, and its pretty heavy on theory with little instruction on coding itself even though you're expected to write projects (as fellow CS majors probably know). We did do a few intro to C++ and Java classes to cover the basics, but usually you're expected to pick up the bulk of it on your own, so I spent a lot of time knowing that some line of code worked but not why it worked, like 'using namespace std;' for instance. I know it needs to be there, but not why. I really want to eventually have a strong understanding of languages, coding and good practices. Does anyone have any recommendations as to books/sites to read? (Something readable; not a 'textbook' with examples accompanied by poor explanations, which is what I'm used to unfortunately) Soxbox already mentioned Thinking in Java, and a friend has told me about the Pragmatic Programmer. I'm not just looking for Java of course. :)

    samsam7 on
  • Options
    soxboxsoxbox Registered User regular
    edited February 2010
    Earlier editions of Thinking in Java (http://www.mindview.net/Books/TIJ/) and Programming Ruby: A pragmatic programmer's guide (http://ruby-doc.org/docs/ProgrammingRuby/) are both available online for free. They're also pretty much two of the best written programming text books you're likely to ever come across.

    I'd recommend reading both as they cover two quite different languages with different philosophies.

    Surgeon Generals Warning: Programming in ruby may lead to a disdain for other programming languages that may make sitting through c++ classes unbearable.

    I'll also repeat the advise that I just gave in the other thread: Avoid any sort of GUI programming. Most GUI programming will lead you into a world of propriety and poorly designed libraries that will cultivate a lot of extremely bad habits. If you want to put a GUI on something, learn web development.

    soxbox on
  • Options
    TavataarTavataar Registered User regular
    edited February 2010
    samsam7 wrote: »
    Nope, no red squiggly lines. Eclipse was showing no errors until I tried compiling and running. Maybe I had some setting checked or something.

    Ahh, you might have had "Auto Build" turned off. If you want Eclipse to check your code for compile-time errors while you are writing code you can turn it on up in the Project menu.

    Tavataar on
    -Tavataar
  • Options
    samsam7samsam7 Registered User regular
    edited February 2010
    soxbox wrote: »
    I'll also repeat the advise that I just gave in the other thread: Avoid any sort of GUI programming. Most GUI programming will lead you into a world of propriety and poorly designed libraries that will cultivate a lot of extremely bad habits. If you want to put a GUI on something, learn web development.

    Could you elaborate why web development is superior? I once had to write an electronic phonebook in Java which was quite unpleasant but it was my first attempt at GUI. Aren't a lot of online games and applets written in Java?

    samsam7 on
  • Options
    soxboxsoxbox Registered User regular
    edited February 2010
    Web development enforces a clear separation of the layers of the application and a clearly specified manner for those two layers to interact. The interactions are simple - user requests data, server responds with data, user submits data, server processes data.

    Web development isn't superior for everything - some things aren't even possible in a web development world - but the structure that it provides for you creates a much much much better learning environment than any GUI framework would.

    You're also much more likely to develop a useful web application than you are to develop a useful GUI application.

    soxbox on
  • Options
    admanbadmanb unionize your workplace Seattle, WARegistered User regular
    edited February 2010
    samsam7 wrote: »
    soxbox wrote: »
    I'll also repeat the advise that I just gave in the other thread: Avoid any sort of GUI programming. Most GUI programming will lead you into a world of propriety and poorly designed libraries that will cultivate a lot of extremely bad habits. If you want to put a GUI on something, learn web development.

    Could you elaborate why web development is superior? I once had to write an electronic phonebook in Java which was quite unpleasant but it was my first attempt at GUI. Aren't a lot of online games and applets written in Java?

    GUI programming is a big ol' blog on top of "normal" software development that's generally a bit ass. I think what samsam is trying to say is that you should learn how to program before you learn how to create a GUI. Otherwise, you're apt to carry over (bad) habits from GUI programming into regular programming.

    Client-side Java is pretty uncommon on the web. Most online games are written in Flash.

    admanb on
Sign In or Register to comment.