I have directory with many files in it - each with over 800 lines in it. Hovewer, when I try to read it using Scanner, it seems empty.
File f1 = new File("data/cityDistances/a.txt"),
f2 = new File("data/cityDistances/b.txt");
System.out.println(f1.exists() && f2.exists()); //return true
System.out.println(f1.getTotalSpace() > 0 && f2.getTotalSpace() > 0); //return true
Scanner in = new Scanner(f1);
System.out.println(in.hasNext()); // return false;
System.out.println(in.hasNextLine()); //return false;
Why can it behave like that?
I've managed to do it using BufferedReader. Nonetheless, it seems even more strange that BufferedReader works and Scanner didn't.
As the default delimeter for Scanner is whitespace, that would imply your a.txt contains only whitespace - does it have 800 lines of whitespace? ;)
Have you tried the following?
new Scanner(new BufferedReader(new FileReader("a.txt")));
I had a similar problem today reading a file with Scanner.
I specified the encoding type of the file and it solved the problem.
scan = new Scanner(selectedFile,"ISO-8859-1");
This also happened to me today. I'm reading a plain text file from a Linux system written by some application in a Windows box and Scanner.hasNextLine() is always false even tough there are lines with the Windows line separator and all. As said by Hound Dog, by using
Scanner scanner = new Scanner(new BufferedReader(new FileReader(file)));
it worked like a charm. FileReader or BufferedReader seem to properly identify and use some file characteristics.
Checking the scanner's exception may show that the file can't be read.
...
System.out.println(in.hasNext()); // return false;
IOException ex = in.ioException();
if (ex != null)
ex.printStackTrace(System.out);
...
The function File.getTotalSpace() is not behaving how you're expecting. It is returning the size of the partition where those particular files are located.
You want to use File.length().
refer to file address you are using linux, refer to your name there is possible some Polish or Czech character and refer to below link, scanner dont like non utf-8 characters on linux:)
http://karussell.wordpress.com/2008/09/04/encoding-issues-solutions-for-linux-and-within-java-apps/
This probably doesn't answer the OP's question, but for anyone else who is experiencing "my iterator's hasNext() is always false!"--if you have a bunch of watches with .next() in them, your IDE or whatever is actually advancing the cursor position per each one. This has caused me much trouble. Be careful with iterators and watches.
Related
I am trying to make a smaller version of Pwned Passwords (https://haveibeenpwned.com/Passwords) for my Ap comp sci project. Everything is goo besides 2 things:
(Issue 1) (image of my code to show better)
I have this below my jForm source code which declares each button/etc and what they do. I get this error though: "Illegal static declaration in inner class PassCheck.check. I do not now how to resolve this issue.
The second issue is using FileReader and Buffered Reader. I want the program to read the text inputted from the jForm and compare it to a file which has a list of commonly used passwords. How can I do this? Here is my code so far of just practicing with FR and BR:
import java.io.*;
public class MainFileReader {
public static void main(String[] args) throws Exception{
String refpass, input;
input = "1234";
FileReader fr = new FileReader("C:\\Users\\tcoley\\Downloads\\207pass.txt");
BufferedReader br = new BufferedReader(fr);
while((input = br.readLine()) != null){
refpass = br.readLine();
And I stopped here. I apologize as Java is not my strong suit but any help is much appreciated!
For your issue #2 - input is the string variable that is to be used hold the password you want to find in the file yet you eliminate its contents when you apply it to reading a line: (input = br.readLine()). It will now hold the currently read file line (this is no good). You need to use the refPass variable instead, for example: (refPass = br.readLine()).
You only need to use br.readLine() once in your loop. What your code is effectively doing right now (if it runs) is reading two (2) file lines on each iteration of the while loop. It could potentially fall into an Exception since there is no protection for null in the second read. Again no good.
Once you've read a file line, ensure it actually contains something. A lot of times a file will have a blank line in it that can throw a monkey wrench into things if it's not handled. To check for this you can do something like what is shown below after a line is read into refPass:
while((refPass = br.readLine()) != null) {
// remove leading & trailing whitespaces (if any).
refPass = refPass.trim();
// Skip past blank lines in file (if any).
if (refPass.isEmpty()) {
continue;
}
// .... rest of code ...
}
Now to complete your loop block code, you just need to compare the password read in with the password contained within the input variable (ex: "1234"). To do this, you could have something like this:
if (refPass.equals(input) {
System.out.println("Password Found!")
break; // Break out of the 'while' loop and close file.
}
On a side: Don't use == to compare Strings for content equality, that may not always work as you expect. Use the String#equals() method instead. Give the supplied link a read.
At the end of and outside your while loop, be sure to close the reader, for example: br.close(); so as to release hold on the file and free up resources.
You don't need to use BufferedReader. Buffering is only for inefficient reading and writing (ie doing multiple reads and writes)
Use Path and Files instead
Path p = "C:\\Users\\tcoley\\Downloads\\207pass.txt";
String file = new String(Files.loadAllBytes(p));
What does the file look like? There are a lot of ways to format a file and for simplicities sake, this will just assume it's one word per line:
With the line
refpass = br.readLine();
You are taking in the line from the file
boolean isEqual = refpas.equals(input);
This allows you to assess the line individually.
Remember that '==' is not the way to use String comparisons in Java.
("cat" == "cat") != ("cat".equals("cat"))
I have several files (actually they are also java source files saved in Eclipse on Ubuntu) which I need to read and process line by line. I've noticed that I cannot read one of the files. The code I am using is as below
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine() ) {
builder.append(scanner.nextLine()).append("\n");
}
} catch (FileNotFoundException ex) {
System.out.println("Error");
}
I was checking beforehand if the file exists. And it does. I can even rename it. But I cannot read a single line. hasNextLine simply returns false. (I even try hasNext).
At the end I take a look at the content of the file and find that there is a different looking character (which was in the comment section of java file). It is the following character.
ΒΈ
When I delete this character, I can read the file normally. However this is not acceptable. What can I do to read the files even with that character in it?
This is most probably a character set issue, caused by the fact that the platform you are running your java code uses by default a different set; it is always a good practice to specify the expected/needed character set to be used when parsing, and with the Scanner class is just a matter of calling the constructor as:
Scanner scanner = new Scanner(file, "UTF-8");
where the second parameter is the character set literal, or even better:
Scanner scanner = new Scanner(file, StandardCharsets.UTF_8);
I have a text file (file.txt) which contains multiple lines:
/location/test/file.csv
/location/test1/file2.csv
/location/test2/file.exe
Using ECMA, I would like to replace all instance of "/" with "\". However, the code below only replaces the first line and eliminate lines 2 and 3.
This is the result of the file.txt file after I run the code (as I said, lines 2 and 3 are missing):
\location\test\file.csv
Can anyone please help?
function ReadFile ()
{
var file = new java.io.BufferedReader(new java.io.FileReader("C:\\Test\\file.txt"));
var fileWriter = new java.io.FileWriter("C:\\Test\\file.txt",false);
while ((line = file.readLine()) != null)
{
println(line);
if (line.contains ("/"))
line = line.replace("/","\\");
fileWriter.write(line);
fileWriter.close();
}
}
ReadFile ();
So I managed to run this code using Rhino. It does in fact run. I made some changes to filenames in order to get it running on my mac, but it is essentially the same code:
function ReadFile () {
var file = new java.io.BufferedReader(new java.io.FileReader("file"));
var fileWriter = new java.io.FileWriter("file2",false);
while ((line = file.readLine()) != null) {
if (line.contains ("/"))
line = line.replace("/","\\");
fileWriter.write(line + "\n");
}
fileWriter.close();
file.close();
}
ReadFile ();
So the bugs you had were:
Reading and writing to the same file. This is awkward using streams. Basically, don't do it. I changed it to write to file2.
Closing the writer inside your reader loop. Close the writer at the end, once closed, you can no longer write to it.
Not closing the file you are reading from.
For those interested in how I got this running, on OS X, using rhino:
brew install rhino
rhino example.js
I had to remove the println because that wasn't recognised but that wasn't a critical part. JS on the JVM. Fun! Except nothing is async.....
There are other JS engines too, but rhino worked.
JavaScript String object has a replace method that takes a regular expression that can replace characters in a String. However, the Java in your JavaScript won't work because you are mixing up two languages.
http://www.w3schools.com/jsref/jsref_replace.asp
The problem is that you're writing over the file as you're reading it, so as soon as your first write(line) completes, the file no longer has the next two lines. Either use a second, temporary file to write to until you've finished processing the file, or keep a list/array of all the new lines in memory, and then write out the file at the end.
I'm really curious to know, though, how you managed to get your current program to even run. In my experience, Java and ECMA/Javascript are two completely separate languages, but it looks like you're using javascript code against Java libraries. What's up with that?
I am trying to load a text file from the root of my .jar file. I have tried something like this:
InputStream is = getClass().getResourceAsStream("/infobook.txt");
Scanner scan = new Scanner(is);
ArrayList<String> strings = new ArrayList<String>();
while(scan.hasNextLine())
{
strings.add(scan.nextLine());
}
I do not get any runtime exceptions, however, no lines are added to the ArrayList. I then tried something like System.out.println(scan.nextLine()); and I got a java.util.NoSuchElementException: No line found exception.
Now I am pretty stuck and need your help. The text file has 21 lines of text.
How would I go about loading this text file from the jar?
[edit]
I have also tried reading the input stream like this:
InputStream is = getClass().getResourceAsStream("/infobook.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
System.out.println(br.readLine());
Giving the following error: java.util.zip.ZipException: invalid stored block lengths
I would check there is not a file in your classpath (one you don't expect) which is empty. Try printing
// print where the file is found.
System.out.println(getClass().getResource("/infobook.txt"));
I have tried to create similar scenario but all time I have runned successfully. But even if you give wrong file name, It create different exception. I mean Scanner cannot read it
Maybe there is a character set problem; select this explicitly.
Scanner scan = new Scanner(is, "Windows-1252");
if you are viewing this in the future -
If you are on OSX, try updating your java. That worked for me and may work for you too. Otherwise, do try the other answers below/above.
I have a Java code that reads through an input file using a buffer reader until the readLine() method returns null. I need to use the contents of the file again indefinite number of times. How can I read this file from beginning again?
You can close and reopen it again. Another option: if it is not too large, put its content into, say, a List.
Buffer reader supports reset() to a position of buffered data only. But this cant goto the begin of file (suppose that file larger than buffer).
Solutions:
1.Reopen
2.Use RandomAccessFile
A single Reader should be used once to read the file. If you want to read the file again, create a new Reader based on it.
Using Guava's IO utilities, you can create a nice abstraction that lets you read the file as many times as you want using Files.newReaderSupplier(File, Charset). This gives you an InputSupplier<InputStreamReader> that you can retrieve a new Reader from by calling getInput() at any time.
Even better, Guava has many utility methods that make use of InputSuppliers directly... this saves you from having to worry about closing the supplied Reader yourself. The CharStreams class contains most of the text-related IO utilities. A simple example:
public void doSomeStuff(InputSupplier<? extends Reader> readerSupplier) throws IOException {
boolean needToDoMoreStuff = true;
while (needToDoMoreStuff) {
// this handles creating, reading, and closing the Reader!
List<String> lines = CharStreams.readLines(readerSupplier);
// do some stuff with the lines you read
}
}
Given a File, you could call this method like:
File file = ...;
doSomeStuff(Files.newReaderSupplier(file, Charsets.UTF_8)); // or whatever charset
If you want to do some processing for each line without reading every line into memory first, you could alternatively use the readLines overload that takes a LineProcessor.
you do this by calling the run() function recursively, after checking to see if no more lines can be read - here's a sample
// Reload the file when you reach the end (i.e. when you can't read anymore strings)
if ((sCurrentLine = br.readLine()) == null) {
run();
}
If you want to do this, you may want to consider a random access file. With that you can explicitly set the position back to the beginning and start reading again from there.
i would suggestion usings commons libraries
http://commons.apache.org/io/api-release/org/apache/commons/io/FileUtils.html
i think there is a call to just read the file into a byteArray which might be an alternate approach
Not sure if you have considered the mark() and reset() methods on the BufferedReader
that can be an option if your files are only a few MBs in size and you can set the mark at the beginning of the file and keep reset()ing once you hit the end of the file. It also appears that subsequent reads on the same file will be served entirely from the buffer without having to go to the disk.
I faced with the same issue and came wandering to this question.
1. Using mark() and reset() methods:
BufferedReader can be created using a FileReader and also a FileInputStream. FileReader doesn't support Mark and Reset methods. I got an exception while I tried to do this. Even when I tried with FileInputStream I wasn't able to do it because my file was large (even your's is I guess). If the file length is larger than the buffer then mark and reset methods won't work neither with FileReader not with FileInputStream. More on this in this answer by #jtahlborn.
2. Closing and reopening the file
When I closed and reopened the file and created a new BufferedReader, it worked well.
The ideal way I guess is to reopen the file again and construct a new BufferedReader as a FileReader or FileInputStream should be used only once to read the file.
try {
BufferedReader br = new BufferedReader(new FileReader(input));
while ((line = br.readLine()) != null)
{
//do somethng
}
br.close();
}
catch(IOException e)
{
System.err.println("Error: " + e.getMessage());
}
}