Darshana
Darshana

Reputation: 2548

Non Latin characters shows as '?'

I have a property like name.label=名

My java code is like

Properties properties = new Properties();
try (FileInputStream inputStream = new FileInputStream(path)) {
    Reader reader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
    properties.load(reader);
    System.out.println("Name label: " + properties.getProperty("name.label"));
    reader.close();
} catch (FileNotFoundException e) {
    log.debug("Couldn't find properties file. ", e);
} catch (IOException e) {
    log.debug("Couldn't close input stream. ", e);
}

but it prints

Name label: ?

I am using java 8.

Upvotes: 1

Views: 294

Answers (1)

Holger
Holger

Reputation: 298143

A replacement character may indicate that the file is not encoded with the specified CharSet.

Depending on how you construct the reader, you’ll get different default behavior regarding malformed input.

When you use

Properties properties = new Properties();
try(FileInputStream inputStream = new FileInputStream(path);
    Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {

    properties.load(reader);
    System.out.println("Name label: " + properties.getProperty("name.label"));
} catch(FileNotFoundException e) {
    log.debug("Couldn't find properties file. ", e);
} catch(IOException e) {
    log.debug("Couldn't read properties file. ", e);
}

you get a Reader with a CharsetDecoder configured to replace invalid input. In contrast, when you use

Properties properties = new Properties();
try(Reader reader = Files.newBufferedReader(Paths.get(path))) { // default to UTF-8
    properties.load(reader);
    System.out.println("Name label: " + properties.getProperty("name.label"));
} catch(FileNotFoundException e) {
    log.debug("Couldn't find properties file. ", e);
} catch(IOException e) {
    log.debug("Couldn't read properties file. ", e);
}

the CharsetDecoder will be configured to throw an exception on malformed input.

For completeness, here’s how you can configure the behavior if neither default fits your needs:

Properties properties = new Properties();
CharsetDecoder dec = StandardCharsets.UTF_8.newDecoder()
    .onMalformedInput(CodingErrorAction.REPLACE)
    .replaceWith("!");
try(FileInputStream inputStream = new FileInputStream(path);
    Reader reader = new InputStreamReader(inputStream, dec)) {

    properties.load(reader);
    System.out.println("Name label: " + properties.getProperty("name.label"));
} catch(FileNotFoundException e) {
    log.debug("Couldn't find properties file. ", e);
} catch(IOException e) {
    log.debug("Couldn't read properties file. ", e);
}

See also CharsetDecoder and CodingErrorAction.

Upvotes: 2

Related Questions