RalfB
RalfB

Reputation: 583

Reading / Writing number in Java -- Then NumberFormatException when converting

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

Answers (5)

M A
M A

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

user3735278
user3735278

Reputation: 261

You could do numberString.replaceAll("[^\\d.]", ""); to ensure that no non-numeric characters are attached to your String.

Upvotes: 0

TheJavaCoder16
TheJavaCoder16

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

Elliott Frisch
Elliott Frisch

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

Boris the Spider
Boris the Spider

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:

  • Use Java 7 try-with-resources, don't use finally.
  • Use a Data(Out|In)PutStream and write the numbers directly as binary.
  • Get out of the habit of declaring things as null then reassigning them. For example in this code, if you fail to create writer you will get a NullPointerException in your finally.
  • Avoid static methods unless they are absolutely necessary, for example in a static factory pattern.
  • Make use of the new Path API
  • Make use of the related Files utility class

Upvotes: 1

Related Questions