Reputation: 583
I have a number I write as UTF-8 then read it back in (at a later stage). Then I convert it to a number because I use this number for arithmetics. I get a NumberFormatException but cannot see a reason. I am operating entirely in UTF-8, both ways, is that a problem?
So, the first output is fine and I see my number (as a string). The second output fails with a NumberFormatException.
Here is my code for writing and reading the file:
static public void putContents(File aFile, String content, boolean append) {
// init
Writer writer = null;
// make sure file exists
if (!aFile.exists()) {
Util.createFile(aFile.getAbsolutePath());
}
// write content
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(aFile), "UTF-8"));
writer.write(content);
writer.close();
} catch (IOException e) {
logger.error("Error writing content to file: " + aFile);
} finally {
try {
// Close the writer regardless of what happens
writer.close();
} catch (Exception e) {
logger.error("Error while closing file: " + aFile.getAbsolutePath());
}
}
}
static public void createFile(String filename) {
// protection against accidental overwrite
if (new File(filename).exists()) {
logger.warn("File '" + filename + "' already exists. Nothing done.");
return;
}
// create file with directory structure
File targetFile = new File(filename);
File parent = targetFile.getParentFile();
if (!parent.exists() && !parent.mkdirs()) {
throw new IllegalStateException("Couldn't create dir: " + parent);
}
try {
targetFile.createNewFile();
} catch (IOException e){
logger.error("Error while creating empty file '" + filename + "': " + e.getMessage());
}
}
static public String getContents(File aFile) {
StringBuilder contents = new StringBuilder();
try {
// extract all text from this file
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(aFile), "UTF-8"));
try {
String line = null; //not declared within while loop
while ((line = reader.readLine()) != null) {
contents.append(line);
contents.append(System.getProperty("line.separator"));
}
} finally {
reader.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
return contents.toString();
}
and here how I generate the Exception:
public static void main(String[] args) {
putContents(new File("D:/TEST.TXT"), "122", false);
String numberString = Util.getContents(new File("D:/TEST.TXT"));
logger.info("String: " + numberString);
logger.info("String converted to number: " + Integer.parseInt(numberString));
}
Here output:
16:28:05,109 INFO [main] [Util] String: 122
Exception in thread "main" java.lang.NumberFormatException: For input string: "122"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at at.tuwien.mucke.util.Util.main(Util.java:154)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Process finished with exit code 1
Upvotes: 0
Views: 137
Reputation: 72874
The method getContents
is adding a new line in the returned value. This is causing the method to return 122\r\n
contents.append(System.getProperty("line.separator"));
If you want to remove new lines, you can use:
System.out.println("String converted to number: " + Integer.parseInt(numberString.replaceAll("\r\n", "")));
or you can use
System.out.println("String converted to number: " + Integer.parseInt(numberString.replaceAll("\\s", "")));
which will remove all whitespace characters (denoted by the regex metacharacter \s
) from the returned number.
Upvotes: 2
Reputation: 261
You could do numberString.replaceAll("[^\\d.]", "");
to ensure that no non-numeric characters are attached to your String.
Upvotes: 0
Reputation: 591
If i assume correctly you are trying to make it so that your logger goes to a new line when reading the file, if so then where you put:
logger.info("String: " + numberString);
append +"\n"
to your numberString and it should add a new line. But of course this is highly unnecessary considering Loggers by default write to a new line per logger.info(anyString)
call. Either way, when you parse a String as an Int, the String may only contain integer characters as well as the -
character. The line.separator
String is "\n" usually and is obviously not a number, returning an error.
Upvotes: 0
Reputation: 201467
Your utility method added line separator to your String, so this fails
logger.info("String converted to number: " + Integer.parseInt(numberString));
You could do something like this,
String numberString = Util.getContents(new File("D:/TEST.TXT"));
numberString = (numberString != null) ? numberString.trim() : "0";
// now this is a safe call
logger.info("String converted to number: " + Integer.parseInt(numberString));
Upvotes: 1
Reputation: 61168
You are adding a newline:
while ((line = reader.readLine()) != null) {
contents.append(line);
contents.append(System.getProperty("line.separator"));
}
So you are trying to parse 122\n
which isn't a number. Don't append newlines.
In fact, you are are reading line-by-line then adding back newlines wouldn't it be easier just to write the raw bytes to a String
?
Further comments:
finally
.Data(Out|In)PutStream
and write the numbers directly as binary.null
then reassigning them. For example in this code, if you fail to create writer
you will get a NullPointerException
in your finally
.static
methods unless they are absolutely necessary, for example in a static factory pattern.Path
APIFiles
utility classUpvotes: 1