Unable to read thai characters from .properties resource file in java - java

I have a resource file (.properties file) which is having thai characters.
When I read that file using the below code it is showing junk characters like "?"
package RD1.Common;
import java.util.Enumeration;
import java.util.Locale;
import java.util.ResourceBundle;
public class LabelManagerRD {
public static String[] getLabel(String ParamString1)
{
String NextEle = "";
String str2 = ParamString1;
int i = 1;
String Final[] = new String[1000];
ResourceBundle bundle =
ResourceBundle.getBundle("rd", Locale.US);
Enumeration<String> enumeration = bundle.getKeys();
while (enumeration.hasMoreElements())
{
NextEle = enumeration.nextElement();
if (NextEle.toLowerCase().contains(str2.toLowerCase()))
{
Final[i] = NextEle+"="+bundle.getString(NextEle);
i++;
}
}
return Final;
}
public static void main(String[] args)
{
try
{
String TestValue[] = getLabel("RD.RDRAPCEX");
for(int i=1;i<=TestValue.length;i++)
{
if (!(TestValue[i].length()==0))
{
System.out.println(i+" - "+TestValue[i]);
}
}
}
catch (Exception e)
{
}
}
}
And properties file (rd_en_US.properties) is like below
BL_BLNG_GROUP.BL_BLNG_GRP.BLNG_GRP_ID.IP=รสสรืเ เพนีย รก~^PAGE_1~^Y~^N
BL_BLNG_GROUP.BL_BLNG_GRP.LONG_DESC.IP=Long Desc~^PAGE_1~^Y~^N
BL_BLNG_GROUP.BL_BLNG_GRP.SHORT_DESC.IP=Short Desc~^PAGE_1~^Y~^N
BL_BLNG_GROUP.BL_BLNG_GRP.DETAIL_DESC.IP=Explanatory Note~^PAGE_1~^Y~^N
Please suggest how to proceed with this.
Thanks in advance,
Sandy

If encoding of your file is corrent then you must note that System.out will not be able to print the UTF-8 characters with default console settings. Make sure the console you use to display the output is also encoded in UTF-8.
In Eclipse for example, you need to go to Run Configuration > Common to do this.

Property files are typically interpreted in ISO 8859-1 encoding. If you need other characters not included in this set use unicode escapes like \uxxxx. There are also tools available to convert property files with different encoding to this one (see native2ascii).

Related

to read unicode character in java

i am trying to read Unicode characters from a text file saved in utf-8 using java
my text file is as follows
अ, अदेबानि ,अन, अनसुला, अनसुलि, अनफावरि, अनजालु, अनद्ला, अमा, अर, अरगा, अरगे, अरन, अराय, अलखद, असे, अहा, अहिंसा, अग्रं, अन्थाइ, अफ्रि,
बियन, खियन, फियन, बन, गन, थन, हर, हम, जम, गल, गथ, दरसे, दरनै, थनै, थथाम, सथाम,
खफ, गल, गथ, मिख, जथ, जाथ, थाथ, दद, देख, न, नेथ, बर, बुंथ, बिथ, बिख, बेल, मम,
आ, आइ, आउ, आगदा, आगसिर
i have tried with the code as followed
import java.io.*;
import java.util.*;
import java.lang.*;
public class UcharRead
{
public static void main(String args[])
{
try
{
String str;
BufferedReader bufReader = new BufferedReader( new InputStreamReader(new FileInputStream("research_words.txt"), "UTF-8"));
while((str=bufReader.readLine())!=null)
{
System.out.println(str);
}
}
catch(Exception e)
{
}
}
}
getting out put as
????????????????????????
can anyone help me
You are (most likely) reading the text correctly, but when you write it out, you also need to enable UTF-8. Otherwise every character that cannot be printed in your default encoding will be turned into question marks.
Try writing it to a File instead of System.out (and specify the proper encoding):
Writer w = new OutputStreamWriter(
new FileOutputStream("x.txt"), "UTF-8");
If you are reading the text properly using UTF-8 encoding then make sure that your console also supports UTF-8. In case you are using eclipse then you can enable UTF-8 encoding foryour console by:
Run Configuration->Common -> Encoding -> Select UTF 8
Here is the eclipse screenshot.
You're reading it correctly - the problem is almost certainly just that your console can't handle the text. The simplest way to verify this is to print out each char within the string. For example:
public static void dumpString(String text) {
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
System.out.printf("%c - %04x\n", c, (int) c);
}
}
You can then verify that each character is correct using the Unicode code charts.
Once you've verified that you're reading the file correctly, you can then work on the output side of things - but it's important to try to focus on one side of it at a time. Trying to diagnose potential failures in both input and output encodings at the same time is very hard.

"ResourceBundle" For Entire Files?

Obviously ResourceBundle requires a property file like syntax in the files it finds.
We have a situation where we want to use entire files (in our case HTML-files) as "values". This means that we don't have keys as such. Well, maybe the filename would work as the key.
Here's a directory tree:
src/
main/
resources/
html/
content.html
content_de.html
content_fr.html
content_es.html
order.html
order_de.html
order_fr.html
order_es.html
Now we need logic to find the correct file based on the current locale. If the current locale is German and I'm looking for html/content.html file, it should find html/content_de.html. It doesn't necessarily need to load it right away. Is there some existing mechanism in Java? Do we need to do this manually?
Due to some restrictions, we are currently planning to not use any third-party libraries. So if there is something available in Java 6 SE, it would be our best choice; however, if you know of a third-party library, feel free to name it.
EDIT #1:
An obvious solution would be to have a key in messages.properties to name that HTML-file. While that would work it may become a pain in the butt on the long run (and besides that I don't think this would solve all our issues with this).
EDIT #2: I forgot to say that this is a desktop application.
To make this more ideal, if your naming convention for your files remains consistent (i.e. for each locale, you use the two-letter prefix of the language - meaning 'en' for English, 'fr' for French, and 'es' for Spanish), then this process is extremely straightforward.
We will make use of the Properties class to read the properties in, then use MessageFormat to format the appropriate locale we want from the resultant property.
First, we make a change to the property file - we parameterize it such that we are able to pass in whatever we like.
content=content_{0}.html
order=order_{0}.html
The {0} represents the first parameter to the property.
Now, we only need to load the property in, and pass in the appropriate parameter.
Properties prop = new Properties();
try {
MessageFormat messageFormat = new MessageFormat("");
String property;
// change to suit the locale you wish to serve
String[] param = {"en"};
prop.load(new FileReader(new File("/full/path/to/property/file.properties")));
property = prop.getProperty("content");
messageFormat.applyPattern(property);
System.out.println(messageFormat.format(param));
} catch(IOException ioex) {
System.out.println("no property file here");
}
This prints out:
content_en.html
Ensure that the HTML file you want to access exists before making this call, or turn this into a function which returns String, and ensure that the file exists before it's returned.
To show that I wasn't doing nothing, here are two attempts using an "on our own"-approach:
The first attempt with locale-postfix build up and straight forward loading of resources:
public void attempt1(String baseName, String extension) {
List<String> locales = buildLocaleStrings(Locale.getDefault());
String resourceFound = null;
for (String locale : locales) {
String resourceName = baseName + locale + "." + extension;
URL resource = getClass().getClassLoader().getResource(resourceName);
if (resource != null) {
resourceFound = resourceName;
break;
}
}
System.out.println("found #1: " + resourceFound);
}
private List<String> buildLocaleStrings(Locale localeBase) {
String locale = "_" + localeBase;
List<String> locales = new ArrayList<String>();
while (locale.length() > 0) {
locales.add(locale);
locale = locale.replaceFirst("_[^_]*?$", "");
}
locales.add("");
return locales;
}
The second attempt "abusing" ResourceBundle and its toString():
public void attempt2(String baseName, final String extension) {
ResourceBundle.Control control = new ResourceBundle.Control() {
private String resourceFound = null;
#Override
public List<String> getFormats(String baseName) {
return Arrays.asList(extension);
}
#Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, format);
if (loader.getResource(resourceName) != null) {
resourceFound = resourceName;
return new ResourceBundle() {
#Override
public Enumeration<String> getKeys() {
return null;
}
#Override
protected Object handleGetObject(String key) {
return null;
}
};
}
return null;
}
#Override
public String toString() {
return resourceFound;
}
};
ResourceBundle.getBundle(baseName, control);
System.out.println("found #2: " + control.toString());
}
Sample calls:
public void proof() {
attempt1("html/content", "html");
attempt2("html/content", "html");
}
Both find the same file.
To be honest, I don't like neither.
I know this is an old question but I just came across the exact same problem and I found a more elegant solution. What you need is to delegate locale to file mapping to the standard Java API the same way the API solves translations for keys. So in your example, if the current locale is fr_FR you want to load the files called "content_fr.html" and "order_fr.html", right?
Then simply have a set of resource bundle files and designate a variable to translate the current locale to the closest existing locale:
File translation.properties:
localeCode =
File translation_fr.properties:
localeCode = fr
File translation_en.properties:
localeCode = en
Then you just need to read the value of "localeCode" and concatenate it with "content" and ".html" or "order" and ".html".

Displaying Arabic on Device J2ME

I am using some arabic text in my app. on simulator Arabic Text is diplaying fine.
BUT on device it is not displaying Properly.
On Simulator it is like مَرْحَبًا that.
But on device it is like مرحبا.
My need is this one مَرْحَبًا.
Create text resources for a MIDP application, and how to load them at run-time. This technique is unicode safe, and so is suitable for all languages. The run-time code is small, fast, and uses relatively little memory.
Creating the Text Source
اَللّٰهُمَّ اِنِّىْ اَسْئَلُكَ رِزْقًاوَّاسِعًاطَيِّبًامِنْ رِزْقِكَ
مَرْحَبًا
The process starts with creating a text file. When the file is loaded, each line becomes a separate String object, so you can create a file like:
This needs to be in UTF-8 format. On Windows, you can create UTF-8 files in Notepad. Make sure you use Save As..., and select UTF-8 encoding.
Make the name arb.utf8
This needs to be converted to a format that can be read easily by the MIDP application. MIDP does not provide convenient ways to read text files, like J2SE's BufferedReader. Unicode support can also be a problem when converting between bytes and characters. The easiest way to read text is to use DataInput.readUTF(). But to use this, we need to have written the text using DataOutput.writeUTF().
Below is a simple J2SE, command-line program that will read the .uft8 file you saved from notepad, and create a .res file to go in the JAR.
import java.io.*;
import java.util.*;
public class TextConverter {
public static void main(String[] args) {
if (args.length == 1) {
String language = args[0];
List<String> text = new Vector<String>();
try {
// read text from Notepad UTF-8 file
InputStream in = new FileInputStream(language + ".utf8");
try {
BufferedReader bufin = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String s;
while ( (s = bufin.readLine()) != null ) {
// remove formatting character added by Notepad
s = s.replaceAll("\ufffe", "");
text.add(s);
}
} finally {
in.close();
}
// write it for easy reading in J2ME
OutputStream out = new FileOutputStream(language + ".res");
DataOutputStream dout = new DataOutputStream(out);
try {
// first item is the number of strings
dout.writeShort(text.size());
// then the string themselves
for (String s: text) {
dout.writeUTF(s);
}
} finally {
dout.close();
}
} catch (Exception e) {
System.err.println("TextConverter: " + e);
}
} else {
System.err.println("syntax: TextConverter <language-code>");
}
}
}
To convert arb.utf8 to arb.res, run the converter as:
java TextConverter arb
Using the Text at Runtime
Place the .res file in the JAR.
In the MIDP application, the text can be read with this method:
public String[] loadText(String resName) throws IOException {
String[] text;
InputStream in = getClass().getResourceAsStream(resName);
try {
DataInputStream din = new DataInputStream(in);
int size = din.readShort();
text = new String[size];
for (int i = 0; i < size; i++) {
text[i] = din.readUTF();
}
} finally {
in.close();
}
return text;
}
Load and use text like this:
String[] text = loadText("arb.res");
System.out.println("my arabic word from arb.res file ::"+text[0]+" second from arb.res file ::"+text[1]);
Hope this will help you. Thanks

Reading Java Properties file without escaping values

My application needs to use a .properties file for configuration.
In the properties files, users are allow to specify paths.
Problem
Properties files need values to be escaped, eg
dir = c:\\mydir
Needed
I need some way to accept a properties file where the values are not escaped, so that the users can specify:
dir = c:\mydir
Why not simply extend the properties class to incorporate stripping of double forward slashes. A good feature of this will be that through the rest of your program you can still use the original Properties class.
public class PropertiesEx extends Properties {
public void load(FileInputStream fis) throws IOException {
Scanner in = new Scanner(fis);
ByteArrayOutputStream out = new ByteArrayOutputStream();
while(in.hasNext()) {
out.write(in.nextLine().replace("\\","\\\\").getBytes());
out.write("\n".getBytes());
}
InputStream is = new ByteArrayInputStream(out.toByteArray());
super.load(is);
}
}
Using the new class is a simple as:
PropertiesEx p = new PropertiesEx();
p.load(new FileInputStream("C:\\temp\\demo.properties"));
p.list(System.out);
The stripping code could also be improved upon but the general principle is there.
Two options:
use the XML properties format instead
Writer your own parser for a modified .properties format without escapes
You can "preprocess" the file before loading the properties, for example:
public InputStream preprocessPropertiesFile(String myFile) throws IOException{
Scanner in = new Scanner(new FileReader(myFile));
ByteArrayOutputStream out = new ByteArrayOutputStream();
while(in.hasNext())
out.write(in.nextLine().replace("\\","\\\\").getBytes());
return new ByteArrayInputStream(out.toByteArray());
}
And your code could look this way
Properties properties = new Properties();
properties.load(preprocessPropertiesFile("path/myfile.properties"));
Doing this, your .properties file would look like you need, but you will have the properties values ready to use.
*I know there should be better ways to manipulate files, but I hope this helps.
The right way would be to provide your users with a property file editor (or a plugin for their favorite text editor) which allows them entering the text as pure text, and would save the file in the property file format.
If you don't want this, you are effectively defining a new format for the same (or a subset of the) content model as the property files have.
Go the whole way and actually specify your format, and then think about a way to either
transform the format to the canonical one, and then use this for loading the files, or
parse this format and populate a Properties object from it.
Both of these approaches will only work directly if you actually can control your property object's creation, otherwise you will have to store the transformed format with your application.
So, let's see how we can define this. The content model of normal property files is simple:
A map of string keys to string values, both allowing arbitrary Java strings.
The escaping which you want to avoid serves just to allow arbitrary Java strings, and not just a subset of these.
An often sufficient subset would be:
A map of string keys (not containing any whitespace, : or =) to string values (not containing any leading or trailing white space or line breaks).
In your example dir = c:\mydir, the key would be dir and the value c:\mydir.
If we want our keys and values to contain any Unicode character (other than the forbidden ones mentioned), we should use UTF-8 (or UTF-16) as the storage encoding - since we have no way to escape characters outside of the storage encoding. Otherwise, US-ASCII or ISO-8859-1 (as normal property files) or any other encoding supported by Java would be enough, but make sure to include this in your specification of the content model (and make sure to read it this way).
Since we restricted our content model so that all "dangerous" characters are out of the way, we can now define the file format simply as this:
<simplepropertyfile> ::= (<line> <line break> )*
<line> ::= <comment> | <empty> | <key-value>
<comment> ::= <space>* "#" < any text excluding line breaks >
<key-value> ::= <space>* <key> <space>* "=" <space>* <value> <space>*
<empty> ::= <space>*
<key> ::= < any text excluding ':', '=' and whitespace >
<value> ::= < any text starting and ending not with whitespace,
not including line breaks >
<space> ::= < any whitespace, but not a line break >
<line break> ::= < one of "\n", "\r", and "\r\n" >
Every \ occurring in either key or value now is a real backslash, not anything which escapes something else.
Thus, for transforming it into the original format, we simply need to double it, like Grekz proposed, for example in a filtering reader:
public DoubleBackslashFilter extends FilterReader {
private boolean bufferedBackslash = false;
public DoubleBackslashFilter(Reader org) {
super(org);
}
public int read() {
if(bufferedBackslash) {
bufferedBackslash = false;
return '\\';
}
int c = super.read();
if(c == '\\')
bufferedBackslash = true;
return c;
}
public int read(char[] buf, int off, int len) {
int read = 0;
if(bufferedBackslash) {
buf[off] = '\\';
read++;
off++;
len --;
bufferedBackslash = false;
}
if(len > 1) {
int step = super.read(buf, off, len/2);
for(int i = 0; i < step; i++) {
if(buf[off+i] == '\\') {
// shift everything from here one one char to the right.
System.arraycopy(buf, i, buf, i+1, step - i);
// adjust parameters
step++; i++;
}
}
read += step;
}
return read;
}
}
Then we would pass this Reader to our Properties object (or save the contents to a new file).
Instead, we could simply parse this format ourselves.
public Properties parse(Reader in) {
BufferedReader r = new BufferedReader(in);
Properties prop = new Properties();
Pattern keyValPattern = Pattern.compile("\s*=\s*");
String line;
while((line = r.readLine()) != null) {
line = line.trim(); // remove leading and trailing space
if(line.equals("") || line.startsWith("#")) {
continue; // ignore empty and comment lines
}
String[] kv = line.split(keyValPattern, 2);
// the pattern also grabs space around the separator.
if(kv.length < 2) {
// no key-value separator. TODO: Throw exception or simply ignore this line?
continue;
}
prop.setProperty(kv[0], kv[1]);
}
r.close();
return prop;
}
Again, using Properties.store() after this, we can export it in the original format.
Based on #Ian Harrigan, here is a complete solution to get Netbeans properties file (and other escaping properties file) right from and to ascii text-files :
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
/**
* This class allows to handle Netbeans properties file.
* It is based on the work of : http://stackoverflow.com/questions/6233532/reading-java-properties-file-without-escaping-values.
* It overrides both load methods in order to load a netbeans property file, taking into account the \ that
* were escaped by java properties original load methods.
* #author stephane
*/
public class NetbeansProperties extends Properties {
#Override
public synchronized void load(Reader reader) throws IOException {
BufferedReader bfr = new BufferedReader( reader );
ByteArrayOutputStream out = new ByteArrayOutputStream();
String readLine = null;
while( (readLine = bfr.readLine()) != null ) {
out.write(readLine.replace("\\","\\\\").getBytes());
out.write("\n".getBytes());
}//while
InputStream is = new ByteArrayInputStream(out.toByteArray());
super.load(is);
}//met
#Override
public void load(InputStream is) throws IOException {
load( new InputStreamReader( is ) );
}//met
#Override
public void store(Writer writer, String comments) throws IOException {
PrintWriter out = new PrintWriter( writer );
if( comments != null ) {
out.print( '#' );
out.println( comments );
}//if
List<String> listOrderedKey = new ArrayList<String>();
listOrderedKey.addAll( this.stringPropertyNames() );
Collections.sort(listOrderedKey );
for( String key : listOrderedKey ) {
String newValue = this.getProperty(key);
out.println( key+"="+newValue );
}//for
}//met
#Override
public void store(OutputStream out, String comments) throws IOException {
store( new OutputStreamWriter(out), comments );
}//met
}//class
You could try using guava's Splitter: split on '=' and build a map from resulting Iterable.
The disadvantage of this solution is that it does not support comments.
#pdeva: one more solution
//Reads entire file in a String
//available in java1.5
Scanner scan = new Scanner(new File("C:/workspace/Test/src/myfile.properties"));
scan.useDelimiter("\\Z");
String content = scan.next();
//Use apache StringEscapeUtils.escapeJava() method to escape java characters
ByteArrayInputStream bi=new ByteArrayInputStream(StringEscapeUtils.escapeJava(content).getBytes());
//load properties file
Properties properties = new Properties();
properties.load(bi);
It's not an exact answer to your question, but a different solution that may be appropriate to your needs. In Java, you can use / as a path separator and it'll work on both Windows, Linux, and OSX. This is specially useful for relative paths.
In your example, you could use:
dir = c:/mydir

Read resource text file to String in Java [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
Is there a way to read a text file in the resource into a String?
I suppose this is a popular requirement, but I couldn't find any utility after Googling.
Yes, Guava provides this in the Resources class. For example:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
You can use the old Stupid Scanner trick oneliner to do that without any additional dependency like guava:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
Guys, don't use 3rd party stuff unless you really need that. There is a lot of functionality in the JDK already.
Pure and simple, jar-friendly, Java 8+ solution
This simple method below will do just fine if you're using Java 8 or greater:
/**
* Reads given resource file as a string.
*
* #param fileName path to the resource file
* #return the file's contents
* #throws IOException if read fails for any reason
*/
static String getResourceFileAsString(String fileName) throws IOException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try (InputStream is = classLoader.getResourceAsStream(fileName)) {
if (is == null) return null;
try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr)) {
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
}
}
}
And it also works with resources in jar files.
About text encoding: InputStreamReader will use the default system charset in case you don't specify one. You may want to specify it yourself to avoid decoding problems, like this:
new InputStreamReader(isr, StandardCharsets.UTF_8);
Avoid unnecessary dependencies
Always prefer not depending on big, fat libraries. Unless you are already using Guava or Apache Commons IO for other tasks, adding those libraries to your project just to be able to read from a file seems a bit too much.
For java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
For Java 11:
Files.readString(Paths.get(getClass().getClassLoader().getResource("foo.txt").toURI()));
yegor256 has found a nice solution using Apache Commons IO:
import org.apache.commons.io.IOUtils;
String text = IOUtils.toString(this.getClass().getResourceAsStream("foo.xml"),
"UTF-8");
Guava has a "toString" method for reading a file into a String:
import com.google.common.base.Charsets;
import com.google.common.io.Files;
String content = Files.toString(new File("/home/x1/text.log"), Charsets.UTF_8);
This method does not require the file to be in the classpath (as in Jon Skeet previous answer).
apache-commons-io has a utility name FileUtils:
URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());
String content = FileUtils.readFileToString(myFile, "UTF-8"); // or any other encoding
I like akosicki's answer with the Stupid Scanner Trick. It's the simplest I see without external dependencies that works in Java 8 (and in fact all the way back to Java 5). Here's an even simpler answer if you can use Java 9 or higher (since InputStream.readAllBytes() was added at Java 9):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt")
.readAllBytes());
If you're concerned about the filename being wrong and/or about closing the stream, you can expand this a little:
String text = null;
InputStream stream = AppropriateClass.class.getResourceAsStream("foo.txt");
if (null != stream) {
text = stream.readAllBytes();
stream.close()
}
You can use the following code form Java
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
I often had this problem myself. To avoid dependencies on small projects, I often
write a small utility function when I don't need commons io or such. Here is
the code to load the content of the file in a string buffer :
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("path/to/textfile.txt"), "UTF-8"));
for (int c = br.read(); c != -1; c = br.read()) sb.append((char)c);
System.out.println(sb.toString());
Specifying the encoding is important in that case, because you might have
edited your file in UTF-8, and then put it in a jar, and the computer that opens
the file may have CP-1251 as its native file encoding (for example); so in
this case you never know the target encoding, therefore the explicit
encoding information is crucial.
Also the loop to read the file char by char seems inefficient, but it is used on a
BufferedReader, and so actually quite fast.
If you want to get your String from a project resource like the file
testcase/foo.json in src/main/resources in your project, do this:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
Note that the getClassLoader() method is missing on some of the other examples.
Here's a solution using Java 11's Files.readString:
public class Utils {
public static String readResource(String name) throws URISyntaxException, IOException {
var uri = Utils.class.getResource("/" + name).toURI();
var path = Paths.get(uri);
return Files.readString(path);
}
}
Use Apache commons's FileUtils. It has a method readFileToString
I'm using the following for reading resource files from the classpath:
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Scanner;
public class ResourceUtilities
{
public static String resourceToString(String filePath) throws IOException, URISyntaxException
{
try (InputStream inputStream = ResourceUtilities.class.getClassLoader().getResourceAsStream(filePath))
{
return inputStreamToString(inputStream);
}
}
private static String inputStreamToString(InputStream inputStream)
{
try (Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"))
{
return scanner.hasNext() ? scanner.next() : "";
}
}
}
No third party dependencies required.
At least as of Apache commons-io 2.5, the IOUtils.toString() method supports an URI argument and returns contents of files located inside jars on the classpath:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
With set of static imports, Guava solution can be very compact one-liner:
toString(getResource("foo.txt"), UTF_8);
The following imports are required:
import static com.google.common.io.Resources.getResource
import static com.google.common.io.Resources.toString
import static java.nio.charset.StandardCharsets.UTF_8
package test;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
String fileContent = getFileFromResources("resourcesFile.txt");
System.out.println(fileContent);
} catch (Exception e) {
e.printStackTrace();
}
}
//USE THIS FUNCTION TO READ CONTENT OF A FILE, IT MUST EXIST IN "RESOURCES" FOLDER
public static String getFileFromResources(String fileName) throws Exception {
ClassLoader classLoader = Main.class.getClassLoader();
InputStream stream = classLoader.getResourceAsStream(fileName);
String text = null;
try (Scanner scanner = new Scanner(stream, StandardCharsets.UTF_8.name())) {
text = scanner.useDelimiter("\\A").next();
}
return text;
}
}
Guava also has Files.readLines() if you want a return value as List<String> line-by-line:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
Please refer to here to compare 3 ways (BufferedReader vs. Guava's Files vs. Guava's Resources) to get String from a text file.
Here is my approach worked fine
public String getFileContent(String fileName) {
String filePath = "myFolder/" + fileName+ ".json";
try(InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath)) {
return IOUtils.toString(stream, "UTF-8");
} catch (IOException e) {
// Please print your Exception
}
}
If you include Guava, then you can use:
String fileContent = Files.asCharSource(new File(filename), Charset.forName("UTF-8")).read();
(Other solutions mentioned other method for Guava but they are deprecated)
The following cods work for me:
compile group: 'commons-io', name: 'commons-io', version: '2.6'
#Value("classpath:mockResponse.json")
private Resource mockResponse;
String mockContent = FileUtils.readFileToString(mockResponse.getFile(), "UTF-8");
I made NO-dependency static method like this:
import java.nio.file.Files;
import java.nio.file.Paths;
public class ResourceReader {
public static String asString(String resourceFIleName) {
try {
return new String(Files.readAllBytes(Paths.get(new CheatClassLoaderDummyClass().getClass().getClassLoader().getResource(resourceFIleName).toURI())));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
class CheatClassLoaderDummyClass{//cheat class loader - for sql file loading
}
I like Apache commons utils for this type of stuff and use this exact use-case (reading files from classpath) extensively when testing, especially for reading JSON files from /src/test/resources as part of unit / integration testing. e.g.
public class FileUtils {
public static String getResource(String classpathLocation) {
try {
String message = IOUtils.toString(FileUtils.class.getResourceAsStream(classpathLocation),
Charset.defaultCharset());
return message;
}
catch (IOException e) {
throw new RuntimeException("Could not read file [ " + classpathLocation + " ] from classpath", e);
}
}
}
For testing purposes, it can be nice to catch the IOException and throw a RuntimeException - your test class could look like e.g.
#Test
public void shouldDoSomething () {
String json = FileUtils.getResource("/json/input.json");
// Use json as part of test ...
}
public static byte[] readResoureStream(String resourcePath) throws IOException {
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
InputStream in = CreateBffFile.class.getResourceAsStream(resourcePath);
//Create buffer
byte[] buffer = new byte[4096];
for (;;) {
int nread = in.read(buffer);
if (nread <= 0) {
break;
}
byteArray.write(buffer, 0, nread);
}
return byteArray.toByteArray();
}
Charset charset = StandardCharsets.UTF_8;
String content = new String(FileReader.readResoureStream("/resource/...*.txt"), charset);
String lines[] = content.split("\\n");

Categories