Can't read integer file - java

I'm trying to read data from a file that contains integers, but the Scanner doesn't read anything from that file.
I've tried to read the file from the Scanner :
// switch() blablabla
case POPULATION:
try {
while (sc.hasNextInt()) {
this.listePops.add(sc.nextInt());
}
} catch (Exception e) {
System.err.println("~ERREUR~ : " + e.getMessage());
}
break;
And if I try to print each sc.nextInt() to the console, it just prints a blank line and then stops.
Now when I read the same file as a String:
?652432
531345
335975
164308
141220
1094283
328278
270582
// (Rest of the data)
So, I guess it can't read the file as a list of integers since there's a question mark at the beginning, but the problem is that this question mark doesn't appear anywhere in my file, so I can't remove it. What am I supposed to do?

If the first character in the file is a question mark (?) and its original origin is unknown then it is usually the UTF-8 Byte Order Mark (BOM). This means the file was saved as UTF-8. The Microsoft Notepad application will add a BOM to the saved text file if that file was saved in UTF-8 instead of ANSI. There are also other BOM characters for UTF-16, UTF-32, etc.
Reading a text file as String doesn't look like a bad idea now. Changing the save format of the file can work to but that BOM may have actual intended purpose for another application, so, that may not be a viable option. Let's read the file as String lines (read comments in code):
// Variable to hold the value of the UTF-8 BOM:
final String UTF8_BOM = "\uFEFF";
// List to hold the Integer numbers in file.
List<Integer> listePops = new ArrayList<>();
// 'Try With Resources' used to to auto-close file and free resources.
try (Scanner reader = new Scanner(new File("data.txt"))) {
String line;
int lineCount = 0;
while (reader.hasNextLine()) {
line = reader.nextLine();
line = line.trim();
// Skip blank lines (if any):
if (line.isEmpty()) {
continue;
}
lineCount++;
/* Is this the first line and is there a BOM at the
start of this line? If so, then remove it. */
if (lineCount == 1 && line.startsWith(UTF8_BOM)) {
line = line.substring(1);
}
// Validate Line Data:
// Is the line a String representation of an Integer Number?
if (line.matches("\\d+")) {
// Yes... then convert that line to Integer and add it to the List.
listePops.add(Integer.parseInt(line));
}
// Move onto next file line...
}
}
catch (FileNotFoundException ex) {
// Do what you want with this exception (but don't ignore it):
System.err.println(ex.getMessage());
}
// Display the gathered List contents:
for (Integer ints : listePops) {
System.out.println(ints);
}

Related

BufferedReader.skip() equivalent for lines, not characters

Is there in Java some sort of equivalent to BufferedReader.skip(), that would take number of lines as parameter instead of number of characters?
I want to jump to a specific line in a text file and start reading from that point without the need going thru all the lines of the file and checking against the line number (tens of thousands of them - model obj file).
All the examples I saw were dealing with the checking of line number which is not what I want.
So, the solution is to use FileInputStream.skip().
UPDATE: manually adding system-specific new line separator bytes length to line bytes length at each line iteration solved the problem of erroneous bytes skipping, so now it finally works as expected!
Define some Long variable where you will store the number of bytes to skip. I did that in my main application class (App.class):
public static long lineByteOffset = 0;
Then, in your method/function where you read your lines with BufferedReder make it like this (all my files that I read from are encoded as UTF-8):
File objFile = new File(PATH_TO_YOUR_FILE_HERE);
FileInputStream fir = null;
try {
fir = new FileInputStream(objFile);
} catch (FileNotFoundException e) {
System.err.println("File not found!");
}
fir.skip(App.lineByteOffset);//<--- 1ST IMPORTANT PART: SET HOW MANY BYTES TO SKIP, YOU START WITH 0 FOR THE 1ST TIME
BufferedReader reader = new BufferedReader(new InputStreamReader(fir, "UTF-8"));
int nls = System.getProperty("line.separator").getBytes().length;
String line;
try {
while ((line = reader.readLine()) != null) {
App.lineByteOffset += (long) (line.getBytes().length + nls);//<--- 2ND IMPORTANT PART: INCREASE NUMBER OF BYTES TO SKIP FOR NEXT TIME
/*
DO YOUR STUFF HERE...
IN MY CASE IT RETURNS SPECIFIC BLOCK
WHICH IN EFFECT EXIT THE WHILE LOOP AS NEEDED
SO THAT THE NEXT TIME IT CONTINUE WHERE WE LEFT IT
WITHOUT NEED TO READ THE WHOLE FILE FROM THE START ONCE AGAIN
*/
}
reader.close();
} catch (IOException e) {
System.err.println("Error reading the file");
}

How to read certain lines of a txt file in java?

I want to read only the parts i need to. For example my text file look likes these
Name Age Gender
=====================
Donald 13 Male
John 14 Non-binary
Pooh 42 Female
I only want to read the data but i don't know how because my code reads a .txt file line by line
try {
File myObj = new File("database.txt");
Scanner myReader = new Scanner(myObj);
while (myReader.hasNextLine()) { //to read each line of the file
String data = myReader.nextLine();
String [] array = data.split(" "); //store the words in the file line by line
if(array.length ==5){ // to check if data has all five parameter
people.add(new Person(array[0], array[1],array[2], Double.parseDouble(array[3]), Double.parseDouble(array[4])));
}
}
JOptionPane.showMessageDialog(null, "Successfully Read File","Javank",JOptionPane.INFORMATION_MESSAGE);
myReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
You can simply call myReader.nextLine() twice before entering your loop to ignore the first two lines.
Another approach you can take is to use a RandomAccessFile object instead of a Scanner to process your input. If you know how many characters are in the file before the beginning of your relevant data, you can use the RandomAccessFile object's seek method to skip to the beginning of your input, e.g. if there are 50 characters in the file before your data you can use randomAccessFile.seek(50) and then read the lines with randomAccessFile.readLine().
I would probably recommend using the first method of skipping 2 lines however because it seems more simple and robust.

File manipulation (changing lines in a File) in java

I'm trying to read in a file and change some lines.
The instruction reads "invoking java Exercise12_11 John filename removes the string John from the specified file."
Here is the code I've written so far
import java.util.Scanner;
import java.io.*;
public class Exercise12_11 {
public static void main(String[] args) throws Exception{
System.out.println("Enter a String and the file name.");
if(args.length != 2) {
System.out.println("Input invalid. Example: John filename");
System.exit(1);
}
//check if file exists, if it doesn't exit program
File file = new File(args[1]);
if(!file.exists()) {
System.out.println("The file " + args[1] + " does not exist");
System.exit(2);
}
/*okay so, I need to remove all instances of the string from the file.
* replacing with "" would technically remove the string
*/
try (//read in the file
Scanner in = new Scanner(file);) {
while(in.hasNext()) {
String newLine = in.nextLine();
newLine = newLine.replaceAll(args[0], "");
}
}
}
}
I don't quite know if I'm headed in the correct direction because I'm having some issue getting the command line to work with me. I only want to know if this is heading in the correct direction.
Is this actually changing the lines in the current file, or will I need different file to make alterations? Can I just wrap this in a PrintWriter to output?
Edit: Took out some unnecessary information to focus the question. Someone commented that the file wouldn't be getting edited. Does that mean I need to use PrintWriter. Can I just create a file to do so? Meaning I don't take a file from user?
Your code is only reading file and save lines into memory. You will need to store all modified contents and then re-write it back to the file.
Also, if you need to keep newline character \n to maintain format when re-write back to the file, make sure to include it.
There are many ways to solve this, and this is one of them. It's not perfect, but it works for your problem. You can get some ideas or directions out of it.
List<String> lines = new ArrayList<>();
try {
Scanner in = new Scanner(file);
while(in.hasNext()) {
String newLine = in.nextLine();
lines.add(newLine.replaceAll(args[0], "") + "\n"); // <-- save new-line character
}
in.close();
// save all new lines to input file
FileWriter fileWriter = new FileWriter(args[1]);
PrintWriter printWriter = new PrintWriter(fileWriter);
lines.forEach(printWriter::print);
printWriter.close();
} catch (IOException ioEx) {
System.err.println("Error: " + ioEx.getMessage());
}

Reading a text file to a string ALWAYS results in empty string?

For the record, I know that reading the text file to a string does not ALWAYS result in an empty string, but in my situation, I can't get it to do anything else.
I'm currently trying to write a program that reads text from a .txt file, manipulates it based on certain arguments, and then saves the text back into the document. No matter how many different ways I've tried, I can't seem to actually get text from .txt file. The string just returns as an empty string.
For example, I pass in the arguments "-c 3 file1.txt" and parse the arguments for the file (the file is always passed in last). I get the file with:
File inputFile = new File(args[args.length - 1]);
When I debug the code, it seems to recognize the file as file1.txt and if I pass in the name of a different file, which doesn't exist, and error is thrown. So it is correctly recognizing this file. From here I have attempted every type of file text parsing I can find online, from old Java version techniques up to Java 8 techniques. None have worked. A few I've tried are:
String fileText = "";
try {
Scanner input = new Scanner(inputFile);
while (input.hasNextLine()) {
fileText = input.nextLine();
System.out.println(fileText);
}
input.close();
} catch (FileNotFoundException e) {
usage();
}
or
String fileText = null;
try {
fileText = new String(Files.readAllBytes(Paths.get(filename)), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
I've tried others too. Buffered readers, scanners, etc. I've tried recompiling the project, I've tried 3rd party libraries. Still just getting an empty string. I'm thinking it must be some sort of configuration issue, but I am stumped.
For anyone wondering, the file seems to be in the correct place, when I reference the wrong location an exception is thrown. And the file DOES in fact have text in it. I've quadruple checked.
Even though your first code snippet might read the file, it does in fact not store the contents of the file in your fileText variable but only the file's last line.
With
fileText = input.nextLine();
you set fileText to the contents of the current line thereby overwriting the previous value of fileText. You need to store all the lines from your file. E.g. try
static String read( String path ) throws IOException {
StringBuilder sb = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
for (String line = br.readLine(); line != null; line = br.readLine()) {
sb.append(line).append('\n');
}
}
return sb.toString();
}
My suggestion would be to create a method for reading the file into a string which throws an exception with a descriptive message whenever an unexpected state is found. Here is a possible implementation of this idea:
public static String readFile(Path path) {
String fileText;
try {
if(Files.size(path) == 0) {
throw new RuntimeException("File has zero bytes");
}
fileText = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
if(fileText.trim().isEmpty()) {
throw new RuntimeException("File contains only whitespace");
}
return fileText;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
This method checks 3 anomalies:
File not found
File empty
File contains only spaces

How to delete a line from a textfile using java?

I wanted to delete a line from a textfile after asking the user what he/she wants to delete but I don't know what to do next in my code.
The textfile looks like this:
1::name::mobileNum::homeNum::fax::birthday::email::website::address // line the user wants to delete
2::name::mobileNum::homeNum::fax::birthday::email::website::address
3::name::mobileNum::homeNum::fax::birthday::email::website::address
Here's my code:
public static void readFromFile(String ans, String file) throws Exception {
BufferedReader fileIn = new BufferedReader(new FileReader(file));
GetUserInput console = new GetUserInput();
String checkLine = fileIn.readLine();
while(checkLine!=null) {
String [] splitDetails = checkLine.split("::");
Contact details = new Contact(splitDetails[0], splitDetails[1], splitDetails[2], splitDetails[3], splitDetails[4], splitDetails[5], splitDetails[6], splitDetails[7], splitDetails[8]);
checkLine = fileIn.readLine();
if(ans.equals(splitDetails[0])) {
// not sure what the code will look like here.
// in this part, it should delete the line the user wants to delete in the textfile
}
}
}
So the output of the textfile should be like this:
2::name::mobileNum::homeNum::fax::birthday::email::website::address
3::name::mobileNum::homeNum::fax::birthday::email::website::address
Also, I want the line number 2 and 3 to be adjusted to 1 and 2:
1::name::mobileNum::homeNum::fax::birthday::email::website::address
2::name::mobileNum::homeNum::fax::birthday::email::website::address
How would I do this?
Here's a working code, assuming you are using Java >= 7:
public static void removeLine(String ans, String file) throws IOException {
boolean foundLine = false;
try (BufferedReader br = Files.newBufferedReader(Paths.get(file));
BufferedWriter bw = Files.newBufferedWriter(Paths.get(file + ".tmp"))) {
String line;
while ((line = br.readLine()) != null) {
String[] tokens = line.split("::", 2);
if (tokens[0].equals(ans)) {
foundLine = true;
} else {
if (foundLine) {
bw.write((Integer.parseInt(tokens[0]) - 1) + "::" + tokens[1]);
} else {
bw.write(line);
}
bw.newLine();
}
}
}
Files.move(Paths.get(file + ".tmp"), Paths.get(file), StandardCopyOption.REPLACE_EXISTING);
}
It is not possible to delete a line from a file. What you need to do is read the existing file, write the contents you want to keep to a temporary file and then rename the temporary file to overwrite the input file.
Here, the temporary file is created in the same directory as the input file, with the extension .tmp added (note that you can also use Files.createTempFile for this).
For each line that is read, we check if this is the line the user wants to delete.
If it is, we update a boolean variable telling us that we just hit the line to be deleted and we do not copy this line to the temporary file.
If it is not, we have a choice:
Either we did not yet hit the line to be deleted. Then we simply copy what we read to the temporary file
Or we did and we need to decrement the first number and copy the rest of the line to the temporary file.
The current line is splitted with the help of String.split(regex, limit) (it splits the line only two times, thereby creating an array of 2 Strings: first part is the number, second part is the rest of the line).
Finally, the temporary file overwrites the input file with Files.move (we need to use the REPLACE_EXISTING option).

Categories