Java can't read file while deployed on JBoss - java

I'm trying to read a csv file, everything works before is deployed on jboss and I don't know how to solve it:
my loader is this:
public Map<String, String> getScript() throws IOException {
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("scriptSQL.csv").getPath());
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
Map<String, String> map = new HashMap<>();
while ((line = br.readLine()) != null) {
String arr[] = line.split(";");
map.put(arr[0], arr[1]);
}
System.out.println(map);
this.sqlScript = map;
return map;
}
public String getKey(String key) {
if (this.sqlScript != null && this.sqlScript.get(key) != null && !this.sqlScript.get(key).isEmpty()) {
return sqlScript.get(key);
} else {
try {
sqlScript = getScript();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return sqlScript.get(key);
}
The error when is deployed is this:
Caused by: java.io.FileNotFoundException: C:\Program%20Files\wildfly-18.0.0.Final\standalone\deployments\archiconEar.ear\archiconWeb.war\WEB-INF\classes\scriptSQL.csv (Impossible find the path)
how can I say to look in the resource folder and not in this one or anything who could help me please

Use full path to locate your file. Something like below :
File file = new File(classLoader.getResource(PROJECT_PATH+"path\to\your\file\scriptSQL.csv").getPath());
Set PROJECT_PATH using either properties file or system variable.
E.g.
File file = new File(classLoader.getResource(System.getenv("PROJECT_PATH")+"path\to\your\file\scriptSQL.csv").getPath());
This value will be different when you run application directly in local and when you deploy it to run in any server

Better not to mix up your resources with your normal code packages. This uses the csv resource as placed at the root. You'd be better off creating a 'resources' directory for easier demarcation though:
public Map<String, String> getScript() throws IOException {
Map<String, String> map = new HashMap<>();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(getClass().getResourceAsStream("/scriptSQL.csv")))) {
String line = null;
while ((line = br.readLine()) != null) {
String arr[] = line.split(";");
map.put(arr[0], arr[1]);
}
}
System.out.println(map);
this.sqlScript = map;
return map;
}

Related

The system cannot find the file specified - Netbeans Maven Project

I need to read two .json files, I have added them to my src folder of NetBeans folder but it is not finding the file.
I have tried using path in following ways,
"/krf_input_cases.json",
"krf_input_cases.json",
"/com.mycompany.reasoner/krf_input_cases.json"
after checking here on StackOverflow but it is not working. The still same error that file cannot be found!
Here you can see where is my file is in the document tree:
This is where I have specified my file paths
//file paths
private static final String KRF_INPUT_CASES = "krf_input_cases.json";
private static final String KRF_KNOWLEDGE_BASE = "krf_knowledge_base.json";
Here is the function reading the file which is throwing an exception!
public static String loadData(String filePath) throws Exception {
System.out.println("line");
BufferedReader br = null;
try{br = new BufferedReader(new FileReader(
new File(filePath)));} catch (Exception e){
System.out.println(e.getMessage());
}
System.out.println("line1");
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line.trim());
}
br.close();
return sb.toString();
}

File list from classpath directory in running jar

I want to load all resource bundle properties from classpath, so that I can show supported languages. I got a reference from here and tried 1st solution. It works file when I run my code from eclipse. But when I create executable jar file, it could not read files. I don't know why behavior is different while running from command java -jar AppName.jar
My Code Is:
public static List<String> getResourceFiles(String path) throws IOException
{
List<String> filenames = new ArrayList<>();
InputStream in = getResourceAsStream(path);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
System.out.println("br = " + br.readLine());
String resource;
while ((resource = br.readLine()) != null)
{
filenames.add(resource);
}
return filenames;
}
private static InputStream getResourceAsStream(String resource)
{
final InputStream in = getContextClassLoader().getResourceAsStream(resource);
System.out.println("input stream = " + in);
return in == null ? FileUtil.class.getResourceAsStream(resource) : in;
}
private static ClassLoader getContextClassLoader()
{
return Thread.currentThread().getContextClassLoader();
}
Here I noticed that InputStream is null when I run from command, but while running from eclipse InputStream is not null.
How to solve this problem so that I can read resource files when running from command also?
I found solution. Below code worked for me:
public static String[] getResourceListing(Class clazz, String path) throws URISyntaxException, IOException
{
URL dirURL = clazz.getClassLoader().getResource(path);
if (dirURL != null && dirURL.getProtocol().equals("file"))
{
/* A file path: easy enough */
return new File(dirURL.toURI()).list();
}
if (dirURL == null)
{
/*
* In case of a jar file, we can't actually find a directory. Have to assume the
* same jar as clazz.
*/
String me = clazz.getName().replace(".", "/") + ".class";
dirURL = clazz.getClassLoader().getResource(me);
}
if (dirURL.getProtocol().equals("jar"))
{
/* A JAR path */
String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); // strip out only the JAR file
JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
Enumeration<JarEntry> entries = jar.entries(); // gives ALL entries in jar
Set<String> result = new HashSet<String>(); // avoid duplicates in case it is a subdirectory
while (entries.hasMoreElements())
{
String name = entries.nextElement().getName();
if (name.startsWith(path))
{ // filter according to the path
String entry = name.substring(path.length());
int checkSubdir = entry.indexOf("/");
if (checkSubdir >= 0)
{
// if it is a subdirectory, we just return the directory name
entry = entry.substring(0, checkSubdir);
}
result.add(entry);
}
}
return result.toArray(new String[result.size()]);
}
throw new UnsupportedOperationException("Cannot list files for URL " + dirURL);
}

How can I Cache the data I'm reading from a collection of text files in a directory using a TreeMap?

How can I Cache the data I'm reading from a collection of text files in a directory using a TreeMap? Currently my program reads the data from several text files in a directory and the saves that information in a text file called output.txt. I would like to cache this data in order to use it later. How can I do this using the TreeMap Class?
These are the keys,values: TreeMap
The data I'd like to Cache is (date from the file, time of the file, current time).
Here is an example of the data contained in the .text. files.
and
are
as
at
award
awards
be
but
by
centsales
for
he
hello
her
hers
his
if
in
into
is
it
me
mine
no
not
of
on
or
s
such
t
that
the
their
them
then
there
these
they
this
to
was
will
with
you
your
yours
ä»–
他们
ä½ 
你们
我
我们
a
an
and
are
as
at
be
but
by
for
if
in
into
is
it
no
not
import java.io.*;
public class CacheData {
public static void main(String[] args) throws IOException {
String target_dir = "C:\\Files";
String output = "C:\\files\\output.txt";
File dir = new File(target_dir);
File[] files = dir.listFiles();
// open the Printwriter before your loop
PrintWriter outputStream = new PrintWriter(output);
for (File textfiles : files) {
if (textfiles.isFile() && textfiles.getName().endsWith(".txt")) {
BufferedReader inputStream = null;
// close the outputstream after the loop
outputStream.close();
try {
inputStream = new BufferedReader(new FileReader(textfiles));
String line;
;
while ((line = inputStream.readLine()) != null) {
System.out.println(line);
// Write Content
outputStream.println(line);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
}
}
}
Cache means to have it memory, you are already putting each line in memory line = inputStream.readLine() and then discarding that in next loop iteration.
you have mentioned you want to store it in TreeMap, you need to decide what will be the key?, as the TreeMap is sorted, how do you want to sort it ?
import java.io.*;
import java.util.Map;
import java.util.TreeMap;
public class CacheData {
public static void main(String[] args) throws IOException {
String target_dir = "C:\\Files";
String output = "C:\\files\\output.txt";
File dir = new File(target_dir);
File[] files = dir.listFiles();
if (files == null || files.length < 1) {
System.out.println("File list is empty...");
return;
}
// open the Printwriter before your loop
PrintWriter outputStream = new PrintWriter(output);
//( //comparator if you want something else than natural ordering)
Map<String, DataContent> myCachedTreeMap = new TreeMap<String, DataContent>();
for (File textFile : files) {
if (textFile.isFile() && textFile.getName().endsWith(".txt")) {
BufferedReader inputStream = null;
// close the outputstream after the loop
outputStream.close();
String content = "";
try {
inputStream = new BufferedReader(new FileReader(textFile));
String line;
while ((line = inputStream.readLine()) != null) {
content += line;
System.out.println(line);
// Write Content
outputStream.println(line);
}
//create content
DataContent dataContent = new DataContent(System.currentTimeMillis(), textFile.lastModified(), content, textFile.getName());
//add to your map
myCachedTreeMap.put(textFile.getName(),dataContent );
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
}
String fileNameYouWantFromCache = "myFile.txt";
//how to use it.
DataContent dataContent = myCachedTreeMap.get(fileNameYouWantFromCache);
System.out.println(fileNameYouWantFromCache +" : \n"+ dataContent);
}
public static class DataContent {
private long cachedTime; //currentTime
private long lastModifiedTimestamp;
private String contents;
private String fileName; //not sure if you want it
public DataContent(long cachedTime, long lastModifiedTimestamp, String contents, String fileName) {
this.cachedTime = cachedTime;
this.lastModifiedTimestamp = lastModifiedTimestamp;
this.contents = contents;
this.fileName = fileName;
}
public long getCachedTime() {
return cachedTime;
}
public long getLastModifiedTimestamp() {
return lastModifiedTimestamp;
}
public String getContents() {
return contents;
}
public String getFileName() {
return fileName;
}
#Override
public String toString() {
return "DataContent{" +
"fileName='" + fileName + '\'' +
", contents='" + contents + '\'' +
", lastModifiedTimestamp=" + lastModifiedTimestamp +
", cachedTime=" + cachedTime +
'}';
}
}
}
Note that you will have to define "myKey" -- that is how you are going to lookup your treemap.. you should decide how you want to store value (here we are storing the line/string you read from file as your map value)
If you want to separate the rows of each file, you can do this:
Map<String, List<String>> filesAndContents = new TreeMap<>();
for (File textfiles : files) {
if (textfiles.isFile() && textfiles.getName().endsWith(".txt")) {
List<String> lines = new ArrayList<>();
filesAndContents.put(textfiles.getName(), lines);
BufferedReader inputStream = null;
// close the outputstream after the loop
outputStream.close();
try {
inputStream = new BufferedReader(new FileReader(textfiles));
String line;
while ((line = inputStream.readLine()) != null) {
System.out.println(line);
// Write Content
outputStream.println(line);
lines.add(line);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
}
Here, filesAndContents will map the file name into the content lines (in reading order). Because a TreeMap is used, the entries in the map will be sorted by the natural ordering of the file names (i.e. alphabetical order).
Based on your comments, seems like you want to only store the file metadata in the cache. If you're on Java 7/8, you can get this information from BasicFileAttributes:
Map<String, BasicFileAttributes> filesAndMetadata = new TreeMap<>();
for (File textfiles : files) {
if (textfiles.isFile() && textfiles.getName().endsWith(".txt")) {
filesAndMetadata.put(textfiles.getName(),
Files.readAttributes(textFiles.toPath(),
BasicFileAttributes.class));
// ....
If you also need the owner of the file you can get it trough FileOwnerAttributeView like this:
FileOwnerAttributeView ownerAttributeView = Files.getFileAttributeView(
textFiles.toPath(),
FileOwnerAttributeView.class);
You might also consider creating your own wrapper class for holding all the metadata you need to cache.

Parse file values using Java

I'm new to Java and I would like to read this file content using Java:
Filename Type Size Used Priority
/dev/mapper/VolGroup00-LogVol01 partition 524280 0 -1
/dev/mapper/VolGroup00-LogVol02 partition 324280 0 -1
Can you show me some working example with Java 8?
This is the code so far:
private static HashMap<String, HashMap<String, Long>> totalSwap() throws FileNotFoundException, IOException
{
File file = new File("/proc/swaps");
if (!file.exists())
{
System.err.println("/proc/swaps did not exist!");
return null;
}
else if (file.isDirectory())
{
System.err.println("/proc/swaps is a directory, not a file.");
return null;
}
Pattern pattern = Pattern.compile("([\\/A-Za-z0-9]+)[\\s]+([a-z]+)[\\s]+([0-9]+)[\\s]+([0-9]+)[\\s]+([\\-0-9]+).*");
BufferedReader reader = new BufferedReader(new FileReader("/proc/swaps"));
String s = reader.readLine();
while (s != null)
{
Matcher matcher = pattern.matcher(s);
if (matcher.matches())
{
HashMap<String, Long> usageData2 = new HashMap<>();
usageData2.put("allSwap", Long.parseLong(matcher.group(3)));
usageData2.put("utilizedSwap", Long.parseLong(matcher.group(4)));
data.put("First", usageData2);
}
s = reader.readLine();
}
reader.close();
return data;
}
I don't know how to read the FileName column. Finally I would like to get this result:
HashMap</dev/mapper/VolGroup00-LogVol01, HashMap<Size, 524280>
HashMap<Used, 0>>
HashMap</dev/mapper/VolGroup00-LogVol02, HashMap<Size, 334220>
HashMap<Used, 0>>
Can you help to solve this problem?
It may be better to split using a tab delimeter, if i remember correctly, linux is outputting using the tab character.
I have had to improvise with youre code but it should be easy to plug your code back in.
See my example below:
private static HashMap<String, HashMap<String, Long>> totalSwap()
{
HashMap<String, HashMap<String, Long>> data = new HashMap<String, HashMap<String, Long>>();
Pattern pattern = Pattern.compile("([\\/A-Za-z0-9]+)[\\s]+[A-Za-z]+[\\s]+([0-9]+)[\\s]+([0-9]+)[\\s]+([\\-0-9]+).*");
String s = "/dev/mapper/VolGroup00-LogVol01\tpartition\t524280\t0\t-1\n/dev/mapper/VolGroup00-LogVol02\tpartition\t324280\t0\t-1";
String[] columns = s.split("\t");
for (String line : columns) {
HashMap<String, Long> usageData2 = new HashMap<>();
usageData2.put("allSwap", Long.parseLong(columns[2]));
usageData2.put("utilizedSwap", Long.parseLong(columns[3]));
data.put(columns[0], usageData2);
}
return data;
}
Maybe it would be better to use StringTokenizer with delimiter tab("\t") and retrieve required columns.

Read file and get key=value without using java.util.Properties

I'm building a RMI game and the client would load a file that has some keys and values which are going to be used on several different objects. It is a save game file but I can't use java.util.Properties for this (it is under the specification). I have to read the entire file and ignore commented lines and the keys that are not relevant in some classes. These properties are unique but they may be sorted in any order. My file current file looks like this:
# Bio
playerOrigin=Newlands
playerClass=Warlock
# Armor
playerHelmet=empty
playerUpperArmor=armor900
playerBottomArmor=armor457
playerBoots=boot109
etc
These properties are going to be written and placed according to the player's progress and the filereader would have to reach the end of file and get only the matched keys. I've tried different approaches but so far nothing came close to the results that I would had using java.util.Properties. Any idea?
This will read your "properties" file line by line and parse each input line and place the values in a key/value map. Each key in the map is unique (duplicate keys are not allowed).
package samples;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.TreeMap;
public class ReadProperties {
public static void main(String[] args) {
try {
TreeMap<String, String> map = getProperties("./sample.properties");
System.out.println(map);
}
catch (IOException e) {
// error using the file
}
}
public static TreeMap<String, String> getProperties(String infile) throws IOException {
final int lhs = 0;
final int rhs = 1;
TreeMap<String, String> map = new TreeMap<String, String>();
BufferedReader bfr = new BufferedReader(new FileReader(new File(infile)));
String line;
while ((line = bfr.readLine()) != null) {
if (!line.startsWith("#") && !line.isEmpty()) {
String[] pair = line.trim().split("=");
map.put(pair[lhs].trim(), pair[rhs].trim());
}
}
bfr.close();
return(map);
}
}
The output looks like:
{playerBoots=boot109, playerBottomArmor=armor457, playerClass=Warlock, playerHelmet=empty, playerOrigin=Newlands, playerUpperArmor=armor900}
You access each element of the map with map.get("key string");.
EDIT: this code doesn't check for a malformed or missing "=" string. You could add that yourself on the return from split by checking the size of the pair array.
I 'm currently unable to come up with a framework that would just provide that (I'm sure there are plenty though), however, you should be able to do that yourself.
Basically you just read the file line by line and check whether the first non whitespace character is a hash (#) or whether the line is whitespace only. You'd ignore those lines and try to split the others on =. If for such a split you don't get an array of 2 strings you have a malformed entry and handle that accordingly. Otherwise the first array element is your key and the second is your value.
Alternately, you could use a regular expression to get the key/value pairs.
(?m)^[^#]([\w]+)=([\w]+)$
will return capture groups for each key and its value, and will ignore comment lines.
EDIT:
This can be made a bit simpler:
[^#]([\w]+)=([\w]+)
After some study i came up with this solution:
public static String[] getUserIdentification(File file) throws IOException {
String key[] = new String[3];
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String lines;
try {
while ((lines = br.readLine()) != null) {
String[] value = lines.split("=");
if (lines.startsWith("domain=") && key[0] == null) {
if (value.length <= 1) {
throw new IOException(
"Missing domain information");
} else {
key[0] = value[1];
}
}
if (lines.startsWith("user=") && key[1] == null) {
if (value.length <= 1) {
throw new IOException("Missing user information");
} else {
key[1] = value[1];
}
}
if (lines.startsWith("password=") && key[2] == null) {
if (value.length <= 1) {
throw new IOException("Missing password information");
} else {
key[2] = value[1];
}
} else
continue;
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return key;
}
I'm using this piece of code to check the properties. Of course it would be wiser to use Properties library but unfortunately I can't.
The shorter way how to do that:
Properties properties = new Properties();
String confPath = "src/main/resources/.env";
try {
properties.load(new FileInputStream(confPath));
} catch (IOException e) {
e.printStackTrace();
}
String specificValueByKey = properties.getProperty("KEY");
Set<Object> allKeys = properties.keySet();
Collection<Object> values = properties.values();

Categories