• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to read out the content from a file on your local directory?

 
Greenhorn
Posts: 23
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi!

I want to extract the contents of a txt.-file as a String - see attached image.

I have googled a bit, how it might work, using java.io and an ObjectInputStream, but it does not work using this code:


Unfortunatelly I get this error-message and I do not know how to solve that:



Another code, which I have tried out is this one here:


Unfortunately I receive following error-message;



Can anyone please help me to understand what is wrong there and show me how I can read the contents of a txt.-file and save the contents in a String?

regards
Michael


readingContentsFromAFile.PNG
[Thumbnail for readingContentsFromAFile.PNG]
 
Bartender
Posts: 390
47
Firefox Browser MySQL Database Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not at my computer, so I can't help much. You are using the wrong class for reading text. Instead, look into the Reader classes, and maybe the Scanner class. The I/O learning trail from Oracle here is an excellent place to start.

Hope that helps for now.
 
Bartender
Posts: 5465
212
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A simple way is for instance:
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Don't use ObjectInputStream to read text files. ObjectInputStream should only be used to read data that is written by ObjectOutputStream. Piet's code works (although the stream should be closed!), or a BufferedReader that wraps a FileReader (basically, Piet's code does that with some stream wrapping). Java 11 added Files.readString which allows you to read the entire contents with just one simple statement.
 
Michael Mutek
Greenhorn
Posts: 23
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jj Roberts wrote:I'm not at my computer, so I can't help much. You are using the wrong class for reading text. Instead, look into the Reader classes, and maybe the Scanner class. The I/O learning trail from Oracle here is an excellent place to start.

Hope that helps for now.



Thanks a lot - I have checked the docu and have found something to make it work.
Also thanks a lot to all other replies.
Should have mentioned that if posssible, I need to use as a requirement java.io and not java.nio, as well as <= JDK version 10.

Finally this is how my code is looking now and it seems to work:


side-question:
Interestingly if I just print out the Stringbuilder 'content' instead of content.toString(),
I would get the same output - so I wonder what is the purpose of converting Stringbuilders into Strings before reading from a file, i.e. before outputting?
Is it just, that sometimes we want to have the contents in a file saved into a variavle of type String since we want to work further with it?

Like in my case here, I need the contents of a file within a String-variable, which I will pass on to a method which then will create for me a hash using SHA-1, based on the contents of the relvant file.

So is the only reason why we convert Stringbuilders usually into Strings at the end, the mentioned thought above (we need a string variable to proceed) or
are there other reasons behind?
 
Jesse Duncan
Bartender
Posts: 390
47
Firefox Browser MySQL Database Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Looking good. Are you familiar with Java 8 streams? If you are, you could do something like this instead:
which does exactly the same thing with less code, using the io package  . If you're going to do that though, you should rather use Files.lines() as Piet suggested.

Your question about StringBuilder: You should have a look at the docs for System.out. You will find that System.out is a variable which holds a reference to a PrintStream object. Looking at PrintStream's print(Object obj) method you will see that it prints the string it gets by calling String.valueOf(Object obj) on the object passed to it. You will see then that String.valueOf() just returns the the result of calling the object's toString() method.

Does that answer your question? To convert the StringBuilder to a String, you need to call its toString() method. If you just pass it to System.out.print(), though, that will happen automatically.
 
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you print a non-string Java object, the print service calls "toString()" on it. So printing a StringBuilder object or calling the toString() on a StringBuilder object result in exactly the same behavior.

Note for your own sanity's sake: Java has the convention that the "real", that is forward slash may be used as a filepath separator on all OS's, including Windows. So rather than this:

write this:

Because just one dropped backslash can ruin your whole day. Plus it helps if you ever need to run on a non-Windows OS, and that's no longer a rare occurrence. And may get rarer if Microsoft doesn't keep screwing up Windows 10.  

A related note is that you can often virtually eliminate use of explicit file path separators if you use the directory+file constructor:

"File" is actually a misnomer for this class, since it isn't the actual file, but a container for a file path. The directory+file constructor is often useful because you may actually be getting the directory path as a configuration variable rather than having it hard-coded into the program (which tends to break when you go to someone else's computer).

And finally, StringBuilder and StringBuffer are building places in which to assemble String objects from multiple parts, and thus unlike String, they are not fixed-length. Instead, they come with a default internal build space size of 16 characters. If that's not enough to hold the string being built, the buffer will be discarded and replaced by a larger one. This can happen multiple times if you're building a large String, so it's good practice to provide an initial buffer size value to the StringBuilder constructor. Make it at least as large as the largest generally-expected string to be produced and you won't have the overhead of resizing the internal build space.
 
Michael Mutek
Greenhorn
Posts: 23
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for all the detailed replies:)

 
Michael Mutek
Greenhorn
Posts: 23
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:

Note for your own sanity's sake: Java has the convention that the "real", that is forward slash may be used as a filepath separator on all OS's, including Windows. So rather than this:

write this:

Because just one dropped backslash can ruin your whole day. Plus it helps if you ever need to run on a non-Windows OS, and that's no longer a rare occurrence. And may get rarer if Microsoft doesn't keep screwing up Windows 10.  



About this one:
Yeah, I have just copy/pasted the path lazily - anyways, do I understand it correctly that my syntax there "\\\\...\\\\.." is only working on Windows,
while the conventional one ("/../../..") is basically working on any OS?
So when I am using Windows, but someone would test my program on his Linux-OS it would work with the second conventional method, but not with my used one?

edit:
Continueing my own little task, I have faced another problem, which I am not able to solve.
I think it is best to start an own thread for it, which I will do - please let me in hindsight know, if this was the preferred action or if it would have been better to continue to use this thread? Thanks^^
 
Tim Holloway
Saloon Keeper
Posts: 27764
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Michael Mutek wrote:- anyways, do I understand it correctly that my syntax there "\\\\...\\\\.." is only working on Windows,
while the conventional one ("/../../..") is basically working on any OS?
So when I am using Windows, but someone would test my program on his Linux-OS it would work with the second conventional method, but not with my used one?



That is correct. There are historical reasons why path separators on DOS/Windows are backslashes, but it conflicts with Unix escape conventions, and Java is very Unix-like.

And while Windows has the backslash and Unix and its relatives have the forward slash, there have been other path separators. I think that the early Macintosh used ":", a minicomputer I once worked with used ">", and in a sense, IBM mainframes use ".", at least in their legacy naming. Then again, a hierarchical filesystem wasn't a standard of IBM's OS architecture for decades, plus they have a 44-character limit on legacy names, of which only 28 could fit on a magnetic tape label.
 
Marshal
Posts: 79180
377
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would suggest you continue with this thread rather than dividing the discussion into several threads. You can get duplicated advice like that.

Are you familiar with try with resources, which allows you to dispense completely with close() calls?
Have you found out about this method and its overloaded versions, for creating a buffered reader? It is often helpful to know what encoding was used to create the file; since I usually use a Linux box, my text files will default to UTF‑8.
Have you come across a file chooser for finding files. Unfortunately it will only give you a File reference, not a Path directly.
  • Challenge 1: Find the two naughty things I have done in line 3.
  • Challenge 2: Understand line 8.
  • I shall explain the answers later if you need help.

    Would I use a Scanner? Yes, I like Scanners; I know lots of people don't. A Scanner would be particularly useful if you want to process the input text immediately, for example turning a token into a number as it is read. If you simply want to read the whole line, you are probably better off with a buffered reader or one of the stream methods other people have told you about.
     
    Michael Mutek
    Greenhorn
    Posts: 23
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    @Tom Holloway: Thanks for clearing that up and the historical insights:)

    @Campbell Ritchie:
    Hehe, I have learned only yesterday about 'try-with-ressources-statements'.
    From my understanding this statements basically tell the following try-block that one ore more ressources are needed.
    The needed ressources will be then closed automatically at the end -> no close() needed.
    But i have used this already in my code-solution?

    @ your quiz:
    Line 3 - is this Java Swing? I worry that I am not able to comprehend what is happening there - I am gulity in not have been learning up to now Java Swing,
    but learning at the moment JavaFX on the side - will start learning Java Swing later.

    Line 8 - isn't this a smilar strategy I have choosen in my code above?
    You declare a variable of type String and in Line 9 you initialize this variable with your "reader"-object.
    Not the reader always checks if the current line is not empty yet, and then put the current non-empty line as argument in your method below.

    @ keeping everything is this thread:
    I am sorry, but I have read your post too late - in the meanwhile I have already created a new thread...
    I hope this is not a big problem - I will link the newly created Thread here and maybe they can be somehow merged?
    https://coderanch.com/t/731937/java/store-deserialized-objects-List

    regards
    Michael


     
    Campbell Ritchie
    Marshal
    Posts: 79180
    377
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    There is probably an FX class corresponding to JFileChooser. If you are already writing FX, try an FX class first. If you become proficient in FX, you may never need to use Swing. But that isn't either of the naughty things I thought I was doing.
    Yes, you did use something almost identical to line 8. But it is not a case of the line being empty. When the buffered reader reaches the end of the file, it returns null from readLine(). That is how it signals completion of its task. You start by assigning line with whatever is read next, and you need additional () because != has a higher precedence than =. When you have assigned line, you test whether it is null. It there is an empty String, that suggests the enter key has been pressed twice, and readLine() will return a 0‑length String. You may wish to test for empty Strings in the body of the loop, or not.

    I think the subejct of your second thread is different enough from this one to merit a second thread.
     
    Michael Mutek
    Greenhorn
    Posts: 23
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:There is probably an FX class corresponding to JFileChooser. If you are already writing FX, try an FX class first. If you become proficient in FX, you may never need to use Swing. But that isn't either of the naughty things I thought I was doing.
    Yes, you did use something almost identical to line 8. But it is not a case of the line being empty. When the buffered reader reaches the end of the file, it returns null from readLine(). That is how it signals completion of its task.
    Oops, I actually meant this in my brain, but have for some unknown reason (maybe exhaustion^^) stated something which is wrong in my post above.
    Yeah, clearly - the task there is to execute the while-loop as long as there is content in the file, i.e. til the end of the file.
    A single iteration ends apparently when there is a 'new line' incoming - so after every line, a new iteration of the loop will begin.


    You start by assigning line with whatever is read next, and you need additional () because != has a higher precedence than =. When you have assigned line, you test whether it is null. It there is an empty String, that suggests the enter key has been pressed twice, and readLine() will return a 0‑length String. You may wish to test for empty Strings in the body of the loop, or not.
    Ah that is intersting.
    Let's say we have one text-file with two paragraphs, where between thos two paragraphs two or more empty lines are existent, e.g.
     "Hello world!
     
     
     
      Bye"
    In this case, reading from the file using the method would be a problem, since it would think that the file came to an end, after "Hello world!" ?


    I think the subejct of your second thread is different enough from this one to merit a second thread.
    Al right:)



    Thanks so far!
    regards
    Michael:)
     
    Campbell Ritchie
    Marshal
    Posts: 79180
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Michael Mutek wrote:. . .  one text-file with two paragraphs, where between thos two paragraphs two or more empty lines are existent, e.g.
     "Hello world!
     
     
     
      Bye"
    . . . reading from the file using the method would be a problem, since it would think that the file came to an end, after "Hello world!" ? . . .

    No. The readLine() method will return an empty String, not null. It is easy to write if (!line.isEmpty()) ... or similar. Remember the trim() and strip() methods.
    The two naughty things about line 8 are:-
  • 1: It is, in theory, an infinite loop. It will continue to run if no file is selected.
  • 2: Use of ; at the end of the line rather than { /* empty */ } or similar. Line 8 will work with no loop body. You may prefer to show a “try again” notice.
  •  
    Michael Mutek
    Greenhorn
    Posts: 23
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    A nice one - got it - thanks^^
     
    reply
      Bookmark Topic Watch Topic
    • New Topic