Google App Engine - read static files in Java - java

I have an App Engine servlet which creates objects based on a JSON file (stored in a "Resources" folder under WEB-INF). I handle the parsing of the file in a separate class:
public class EventParser
{
static Gson gson = new Gson();
static String fileName = "/SOServices-war/src/main/webapp/WEB-INF/Resources/mockEvents.json";
static File file = new File(fileName);
public static List<Event> readDataFromJSON() throws IOException
{
InputStreamReader inReader = new InputStreamReader(new FileInputStream(file), "UTF-8");
String stringFromRes = null;
try (BufferedReader br = new BufferedReader(inReader))
{
StringBuilder sb = new StringBuilder();
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null)
{
sb.append(sCurrentLine);
sb.append(System.lineSeparator());
}
stringFromRes = sb.toString();
}
catch (IOException e)
{
e.printStackTrace();
}
List<Event> events = new ArrayList<Event>();
Type listOfTestObject = new TypeToken<List<Event>>(){}.getType();
events = gson.fromJson(stringFromRes, listOfTestObject);
return events;
}
}
It is important to point out that this used to work using "WEB-INF/" as path, but I've recreated the project (using the new Maven tutorial) and it has a new folder structure: instead of /war/WEB-INF, it looks like /AppName-war/src/main/webapp/WEB-INF. I don't really understand how it could affect things, but I can't seem to get file reading working again.
So far I've tried:
just using " instead of "WEB-INF/"
putting the files under the webapp folder directly
using the old method
using the string provided in this code snipped, but without the dash at the beginning
Neither of them worked, the files couldn't be found on local development environment (app is not deployed yet).
Update
Big thanks to McDowell for providing me the link, it was a bit different, but it helped a lot. I am now calling the readDataFromJSON() method with a servletContext parameter like so:
List<Event> events = EventParser.readDataFromJSON(this.getServletContext());
And then in the parser:
String filePath = context.getRealPath(fileName);
InputStreamReader inReader = new InputStreamReader(new FileInputStream(new File(filePath)), "UTF-8");
This solves my issue.

Related

How to get include a file outside the Android directory and use it in Android?

I'm trying to build a java program for both Android and JavaFX using a common core directory of code and a platform dependent section for each. One of these platform dependent options is called Resources, which is supposed to load text, image, and (eventually) audio files. The JavaFX version works great, and the skeleton of the program appears and can be used. However, the Android version won't doesn't display anything. I've traced that down to the fact that my resources aren't loading, throwing a variety of Exceptions, for the most part NullPointerExceptions. I'm not sure whether the problem is with the resources not being included or with giving it the wrong place to look in the program. My gradle file currently has the following relevant additions:
sourceSets {
main.java.srcDirs += '../../Both'
main.res.srcDirs += '../../Resources'
}
The ../../Both directory properly gets built into the code, as it properly builds and runs, and the Both Directory and the Android directory uses it.
However, the Resources, which include (for the most part), a number of Art subdirectories.
I have tried the following code for reading the files, mostly from the javafx equivalent (which works):
private static String getPath(String resource)
{
return "/Resources/"+resource;
}
public static ArrayList<String> loadText(String resource)
{
try{
if(filecache.containsKey(resource))
return filecache.get(resource);
InputStream in = R.getClass().getResourceAsStream(getPath(resource));
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
ArrayList<String> lines = new ArrayList<>();
String t;
while((t = reader.readLine()) != null)
lines.add(t);
filecache.put(resource, lines);
return lines;
} catch(Exception e){Debug.log(e.toString());}
return new ArrayList<>();
}
Using some code I found here, I have tried this as well, and a couple of variations of it, with no success. (using the same getPath() method)
ArrayList<String> res = new ArrayList<String>();
try {
InputStream inputStream = new android.content.res.Resources().(getPath(resource));
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
while ( (receiveString = bufferedReader.readLine()) != null ) {
res.add(receiveString);
}
}
return res;
} catch(Exception e){Debug.log("While opening: " + resource);Debug.log(e);}
return new ArrayList<String>();
}
Both of those build, but throw Exceptions and don't load the files.
Any insights into how I might be able to read the files? Thanks!

Java Reading textfile in Runnable JAR file ERROR

I have to make a project for school; it's a game. I load the map from a text file. Currently I do it with a scanner, but I can't manage to get it working in a Runnable JAR file without putting the res file next to the JAR file. I want to get the text file inside; it worked with BufferedImages, but the text file doesn't work. I have this code:
public String ReadTextFile(String path) throws IOException {
String HoldsText= null;
FileReader fr = new FileReader(getClass().getResource(path).toString());
BufferedReader br = new BufferedReader(fr);
while((HoldsText = br.readLine())!= null){
System.out.println(HoldsText);
}
return HoldsText;
}
path = "res/Maps/Map2.txt"
error:
java.lang.NullPointerException
at aMAZEing.TextManager.ReadTextFile(TextManager.java:22)
at aMAZEing.Map.openFile(Map.java:89)
at aMAZEing.Map.<init>(Map.java:31)
at aMAZEing.Board.<init>(Board.java:50)
at aMAZEing.Maze.<init>(Maze.java:24)
at aMAZEing.Maze.main(Maze.java:15)
file structure: http://speedcap.net/sharing/screen.php?id=files/a9/77/a977e8b487f21e67db941a96087561cd.png
This doesn't seem to work though. I've researched a lot but could not find anything that worked for me. I just need the whole text file in a string, the rest is easy with substring and so on.
EDIT!:
The resolution to this was that my path had res in it, and it didn't work because of that. I deleted the res and got "/Maps/Map2.txt" as path, now the file loads and my map is displayed again.
public static String ReadTextFile(String path) throws IOException{
String HoldsText= null;
InputStream is = getClass().getResourceAsStream(path);
InputStreamReader fr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(fr);
StringBuilder sb = new StringBuilder();
while((HoldsText = br.readLine())!= null){
sb.append(HoldsText)
.append("\n");
}
return sb.toString();
}
You need to append the lines and use InputStreamReader instead of FileReader

Cannot find file on netbeans

I'm trying to access a data file to get questions and answers for my "Quiz" application.
If I access the file from the one on my desktop, it works fine. If I drag and drop the file into my netbeans, I cannot seem to access it.
The file is in the package "quiz" along with my other classes.
Here's the code that works but I want to use the netbeans file.
String fileName = "C:/Users/Michael/Desktop/QUIZ.DAT";
try {
//Make fileReader object to read the file
FileReader file = new FileReader(new File(fileName));
BufferedReader fileStream = new BufferedReader(file);
} catch (Exception e) {
System.out.println("File not found");
}
To try and access the file on netbeans I use this but it cannot find it.
String fileName = "quiz/Quiz.DAT";
Try this, where MyClass is the class name. I have assumed the quiz.dat file is in the same package of the class.
InputStream f = MyClass.class.getResourceAsStream("QUIZ.DAT");
BufferedReader bReader = new BufferedReader(new InputStreamReader(f));
StringBuffer sbfFileContents = new StringBuffer();
String line = null;
while ((line = bReader.readLine()) != null) {
sbfFileContents.append(line);
}
System.out.println(sbfFileContents.toString());
JJPA provided proper code. But let me enhance it better.
Project
com.io
test.txt
com.root
AccessFile.java
This is my program structure. I want to access file from package io So here is the code.
package com.root;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class AccessFile {
public static void main(String args[]){
try{
InputStream f = AccessFile.class.getResourceAsStream("../io/test.txt");
BufferedReader bReader = new BufferedReader(new InputStreamReader(f));
StringBuffer sbfFileContents = new StringBuffer();
String line = null;
while ((line = bReader.readLine()) != null) {
sbfFileContents.append(line);
}
bReader.close();
f.close();
System.out.println(sbfFileContents.toString());
}catch(Exception e){
e.printStackTrace();
}
}
}
If you are trying to read a file in your JAVA project and netbeans is not able to find it, put the file in the root directory of your project and it should be able to find it.

How to read a text file directly from Internet using Java?

I am trying to read some words from an online text file.
I tried doing something like this
File file = new File("http://www.puzzlers.org/pub/wordlists/pocket.txt");
Scanner scan = new Scanner(file);
but it didn't work, I am getting
http://www.puzzlers.org/pub/wordlists/pocket.txt
as the output and I just want to get all the words.
I know they taught me this back in the day but I don't remember exactly how to do it now, any help is greatly appreciated.
Use an URL instead of File for any access that is not on your local computer.
URL url = new URL("http://www.puzzlers.org/pub/wordlists/pocket.txt");
Scanner s = new Scanner(url.openStream());
Actually, URL is even more generally useful, also for local access (use a file: URL), jar files, and about everything that one can retrieve somehow.
The way above interprets the file in your platforms default encoding. If you want to use the encoding indicated by the server instead, you have to use a URLConnection and parse it's content type, like indicated in the answers to this question.
About your Error, make sure your file compiles without any errors - you need to handle the exceptions. Click the red messages given by your IDE, it should show you a recommendation how to fix it. Do not start a program which does not compile (even if the IDE allows this).
Here with some sample exception-handling:
try {
URL url = new URL("http://www.puzzlers.org/pub/wordlists/pocket.txt");
Scanner s = new Scanner(url.openStream());
// read from your scanner
}
catch(IOException ex) {
// there was some connection problem, or the file did not exist on the server,
// or your URL was not in the right format.
// think about what to do now, and put it here.
ex.printStackTrace(); // for now, simply output it.
}
try something like this
URL u = new URL("http://www.puzzlers.org/pub/wordlists/pocket.txt");
InputStream in = u.openStream();
Then use it as any plain old input stream
What really worked to me: (source: oracle documentation "reading url")
import java.net.*;
import java.io.*;
public class UrlTextfile {
public static void main(String[] args) throws Exception {
URL oracle = new URL("http://yoursite.com/yourfile.txt");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
Using Apache Commons IO:
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public static String readURLToString(String url) throws IOException
{
try (InputStream inputStream = new URL(url).openStream())
{
return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}
}
Use this code to read an Internet resource into a String:
public static String readToString(String targetURL) throws IOException
{
URL url = new URL(targetURL);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(url.openStream()));
StringBuilder stringBuilder = new StringBuilder();
String inputLine;
while ((inputLine = bufferedReader.readLine()) != null)
{
stringBuilder.append(inputLine);
stringBuilder.append(System.lineSeparator());
}
bufferedReader.close();
return stringBuilder.toString().trim();
}
This is based on here.
For an old school input stream, use this code:
InputStream in = new URL("http://google.com/").openConnection().getInputStream();
I did that in the following way for an image, you should be able to do it for text using similar steps.
// folder & name of image on PC
File fileObj = new File("C:\\Displayable\\imgcopy.jpg");
Boolean testB = fileObj.createNewFile();
System.out.println("Test this file eeeeeeeeeeeeeeeeeeee "+testB);
// image on server
URL url = new URL("http://localhost:8181/POPTEST2/imgone.jpg");
InputStream webIS = url.openStream();
FileOutputStream fo = new FileOutputStream(fileObj);
int c = 0;
do {
c = webIS.read();
System.out.println("==============> " + c);
if (c !=-1) {
fo.write((byte) c);
}
} while(c != -1);
webIS.close();
fo.close();
Alternatively, you can use Guava's Resources object:
URL url = new URL("http://www.puzzlers.org/pub/wordlists/pocket.txt");
List<String> lines = Resources.readLines(url, Charsets.UTF_8);
lines.forEach(System.out::println);
corrected method is deprecated now. It is giving the option
private WeakReference<MyActivity> activityReference;
here solution will useful.

Java getResourceAsStream JAR inside WAR

I have a Java webapp WAR file that depends on multiple jars in it's WEB-INF\lib directory. One of these JARS needs to load some config files by doing class.getClassLoader().getResourceAsStream(...). However the InputStream resturns null. Is there a problem with taking this approach when the JAR is inside a WAR? The app is deployed on Tomcat6.
EDIT MORE INFO:
I'm tring to load in SQL queries from files so I can run them. These are located in a separate DAO jar within the web app's WAR, under WEB-INF/lib
mywebapp.war
-- WEB-INF
-- lib
-- mydao.jar
---- com/companyname/queries
-- query1.sql
-- query2.sql
-- query3.sql
...
CODE USING TO LOAD CLASSES
public class QueryLoader {
private static final Logger LOGGER = Logger.getLogger(QueryLoader.class.getName());
public String loadQuery(String fileName) {
final String newline = "\n";
BufferedReader reader = new BufferedReader(new InputStreamReader(
QueryLoader.class.getClassLoader().getResourceAsStream(
"/com/companyname/queries/" + fileName)));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append(newline);
}
} catch (IOException e) {
LOGGER.error(e);
}
I have also tried changing the getResourceAsStream line to
Thread.currentThread().getContextClassLoader().getResourceAsStream(
without success.
My development environment is MS Windows Vista and but I encounter the same error when running it on this environment and on Ubuntu.
Assuming you're not making the rookie mistake of putting QueryLoader in a different JAR, the only problem I can see is that you're using File.separator yet appear (from your use of \) to be using Windows. When using getResourceAsStream, the separator is always a forward slash (/) just as if you're using a URL.
If I change that I get this:
QueryLoader.class.getClassLoader().getResourceAsStream(
"/com/companyname/queries/" + fileName)
Of course, if QueryLoader is in the com.companyname.queries package (along with the queries themselves) then you should simply do this:
QueryLoader.class.getResourceAsStream(fileName)
Simple as that. (It's documented that Class.getResourceAsStream qualifies relative filenames with the name of the containing package.)
Managed to get it to work by using Spring's resource loader instead
public String loadQuery(String fileName) {
final String newline = "\n";
ApplicationContext ctx = new ClassPathXmlApplicationContext();
Resource res = ctx.getResource("classpath:/com/msi/queries/" + fileName);
BufferedReader reader;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(res.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append(newline);
}
} catch (IOException e) {
LOGGER.error(e);
}
return sb.toString();
}
It should work, but you need to take care that you use the correct class loader.

Categories

Resources