I'm trying to pass the contents of a file into a method as a String and encountering a Null pointer exception. I'm converting the file into a String like so:
import java.io.*;
public class FileHandler {
String inputText = null;
public String inputReader() {
StringBuilder sb = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("in.txt"))));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
String inputText = sb.toString();
//System.out.println(inputText);
}
br.close();
} catch (IOException e) {
e.getMessage();
e.printStackTrace();
}
return inputText;
}
}
This is working fine for me in terms of converting the file to a String, but when I try and pass the output of this into another method I get a null pointer exception here:
char[][] railMatrix = new char[key][inputText.length()];
I copied the contents of the file and passed it in as a normal String like so;
String plain = "The text from the file"
int key = 5;
int offset = 3;
String encrypted = rf.encrypt(plain, key, offset);
System.out.println(encrypted);
String unencrypted = rf.decrypt(encrypted, key, offset);
System.out.println(unencrypted);
And it worked fine. But
String plain = fh.inputReader();
Does not.
So inputReader() seems to work, the methods it's being passed into work, but I'm clearly missing something.
A nod in the right direction would be greatly appreciated, thanks friends.
Your result is stored in a local variable "inputText" and you are returning instance level variable which is null and is never reassigned. Remove String type as below and it should work:
while ((line = br.readLine()) != null) {
sb.append(line);
inputText = sb.toString();
//System.out.println(inputText);
}
Related
I have a function in which I am trying to replace ${schema} in a file with a variable pass into the parameter.
So for example
sample.sql
insert into ${schema}.table values (1,2,3);
What i want to achieve when running this function is
sample.sql
insert into public.table values (1,2,3);
So my function does below
public static void setvariable_java(String scriptName, String replaceString){
File ftmp = new File("./src/tempsqlStatements/" + scriptName + ".sql");
String pattern = "\\$\\{schema\\}";
try{
BufferedReader br = new BufferedReader(new FileReader(ftmp));
String ln;
while((ln = br.readLine()) != null)
{
ln = ln.replace("${schema}", "");
System.out.println(ln);
}
}catch (Exception s){
s.printStackTrace();
}
}
And I am running the function
setvariable_java("sample","public")
However, in my sql file, the ${schema} is not getting replaced by sample and it is still giving me when i println.
insert into ${schema}.table values (1,2,3);
Is there anything Im doing wrong?
Edit: I am able to successfully write to the file using filewriter.
public static void setvariable_java(String scriptName, String searchString, String replaceString){
FileWriter writer = null;
String oldContent = "";
try{
BufferedReader br = new BufferedReader(new FileReader(ftmp));
String ln;
while((ln = br.readLine()) != null)
{
ln = ln.replace("${schema}", replaceString);
//System.out.println(ln);
oldContent = oldContent + ln + System.lineSeparator();
}
System.out.println(oldContent);
writer = new FileWriter (ftmp);
writer.write(oldContent);
writer.close();
}catch (Exception s){
s.printStackTrace();
}
}
Do not use regex replace when you don't need regex!
ln = ln.replace("${schema}", replaceString);
Notes:
replace() still replaces all instances, but does a plain text match (not a regex match)
you must assign the result of the replace to the variable. Strings are immutable - replace() (or replaceAll()) returns a new String.
I am using the following code to get data from a file
try {
InputStreamReader inputStreamReader = new InputStreamReader(openFileInput(TEXTFILE));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String string;
StringBuilder stringbuilder = new StringBuilder();
while ((string=bufferedReader.readLine())!=null){
stringbuilder.append(string);
}
EditText.setText(stringbuilder.toString());
} catch (Exception e) {
e.printStackTrace();
}
It works but
when I put the string=bufferedReader.readLine() before While, I get an exception : java.lang.OutOfMemoryError
You're reading a line from the BufferedReader, and storing the result in string. After that, you check if string != null, and if not, you append string to stringbuilder. You're repeating this until string == null.
The confusion here might be the comparison of an assignment statement:
while ((string = bufferedReader.readLine()) != null) { ... }
This is a short notation of the following:
string = bufferedReader.readLine();
while (string != null) {
...
string = bufferedReader.readLine();
}
I'm simply trying to create JSON object like that:
JSONObject jsonObject = new JSONObject(new JsonUtility().execute(UrlUtility.url + "/" + lessonUrl).get());
Error occurs here ^ with message received in catch block:
org.json.JSONException: End of input at character 0 of
JsonUtility class as follows (I belive problem lies not there but still):
private class JsonUtility extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String result = "";
try {
InputStream inputStream = new URL(params[0]).openStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"), 8);
StringBuilder sBuilder = new StringBuilder();
// Reading Json into StringBuilder
String line = null;
while ((line = bReader.readLine()) != null) {
sBuilder.append(line + "\n");
}
inputStream.close();
// Converting Json from StringBuilder to String
result = sBuilder.toString();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
You see that response is concatenated from strings (due to application logic). The final string is: http://itvdn-api.azurewebsites.net/api/courses/test-driven-development/tdd-introduction. As you see when I redirect to that link it gives JSON response.
I have tried to evaluate this UrlUtility.url and received that:
That weird ending of char array confuses me. Perhabs its the problem. Tried to replace those characters using String.replaceAll("'\u0000'0", "" ). Didnt work.
Please help. Will appreciate any ideas. Thanks.
EDIT:
Also, when I hardcode link as:
JSONObject jsonObject = new JSONObject(new JsonUtility().execute("http://itvdn-api.azurewebsites.net/api/courses/test-driven-development/tdd-introduction").get());
It works!
EDIT #2 # ρяσѕρєя K
result = sBuilder.toString(); is empty - "" since it can't parse that concatenated string.
Note: I've been using the same parser with different links in this application e.g. http://itvdn-api.azurewebsites.net/api/courses and that was working fine (but there was no concatenation with link)
/**
* Convert InputStream into String
* #param is
* #return
* #throws IOException Throws an IO Exception if input stream cannot be read
*/
public static String stringFromInputStream(InputStream is) throws IOException {
if (is != null) {
byte[] bytes = new byte[1024];
StringBuilder x = new StringBuilder();
int numRead = 0;
while ((numRead = is.read(bytes)) >= 0)
x.append(new String(bytes, 0, numRead));
return x.toString();
}
else {
return "";
}
}
Use this method for reading the inputstream and get the string.
I have a code which parses strings from an CSV.-file (with twitter data) and gives them to a new KML file. When i parse the comments from the twitter data there are of course unknown tokens like: 🚨. When i open up the new KML-File in Google Earth i get an error because of this unknown tokens.
Question:
When i parse the strings, can i tell java it should throw out all unknown tokens from the string so that i don't have any unknown tokens in my KML?
Thank you
Code below:
String csvFile = "twitter.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ";";
String[] twitter = null;
int row_desired = 0;
int row_counter = 0;
String[] placemarks = new String[1165];
// ab hier einlesen der CSV
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
if (row_counter++ == row_desired) {
twitter = line.split(cvsSplitBy);
placemarks[row_counter] =
"<Placemark>\n"+
"<name>User ID: "+twitter[7]+"</name>\n"+
"<description>This User wrote: "+twitter[5]+" at the: "+twitter[6]+"</description>\n"+
"<Point>\n"+
"<coordinates>"+twitter[1]+","+twitter[2]+"</coordinates>\n"+
"</Point>\n"+
"</Placemark>\n";
row_desired++;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
for(int i = 2; i <= 1164;i++){
String kml2 = kml.concat(""+placemarks[i]+"");
kml=kml2;
}
kml = kml.concat("</Document></kml>");
FileWriter fileWriter = new FileWriter(filepath);
fileWriter.write(kml);
fileWriter.close();
Runtime.getRuntime().exec(googlefilepath + filepath);
}
Text files are not all built equal: you must always consider what character encoding is in use. I'm not sure about Twitter's data specifically, but I would guess they're doing like the rest of the world and using UTF-8.
Basically, avoid FileReader and instead use the constructor of InputStreamReader which lets you specify the Charset.
Tip: if you're using Java 7+, try this:
for (String line : Files.readAllLines(file.toPath(), Charset.forName("UTF-8"))) { ...
More Info
The javadoc of FileReader states "The constructors of this class assume that the default character encoding"
You should avoid this class, always. Or at least for any data that might ever be transferred between computers. Even a program running on Windows "using the default charset" will assume UTF-8 when run from inside Eclipse, or ISO_8859_1 when running outside Eclipse! Such non-determinism from a class is not good.
I want to get information from a script so i used this function
public static HashMap<String, String> getEnvVariables(String scriptFile,String config) {
HashMap<String, String> vars = new HashMap<String, String>();
try {
FileInputStream fstream = new FileInputStream(scriptFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
String var= "if [ \"$1\" = \""+config +"\" ] ; then";
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
// use a Scanner to parse the content of each line
// exclude concatenated variables (export xx:$xx)
if (strLine.startsWith("export") && !strLine.contains("$")) {
strLine = strLine.substring(7);
Scanner scanner = new Scanner(strLine);
scanner.useDelimiter("=");
if (scanner.hasNext()) {
String name = scanner.next();
String value = scanner.next();
System.out.println(name+"="+value);
vars.put(name, value);
}
}
}
However i want to begin reading from a particular line which is
if [ \"$1\" = \""+config +"\" ] ; then
the problem is that when a line begins with a space the program considers that the file have ended !
So how can i fix it and make the program pars to the end of file ?
considering that the line could begin with more thant one space
thx
You may try to trim the irrelevant spaces from every line ?
while ((strLine = br.readLine().trim()) != null) {...}
Edit : don't do that (thanks Joop Eggen!) or you'll have a nice NPE...). Try:
while ((strLine = br.readLine()) != null) {
strLine = strLine.trim();
...
}
Sounds for me like you should use regular expressions (e.g. use the String.matches() method). They also can extract strings or substrings (see: another Stackoverflow article).
There is also an excellent introduction by Lars Vogella about regular expressions in Java. Oracle compiled also a Tutorial/Lesson about that topic.
May be this snippet helps a bit (uses org.apache.commons.io.LineIterator):
public void grepLine(File file, String regex)
{
LineIterator it = FileUtils.lineIterator(file, "UTF-8");
try
{
while (it.hasNext())
{
String line = it.nextLine();
if(line.matches(regex))
{
//...do your stuff
}
}
}
finally
{
LineIterator.closeQuietly(it);
}
}
The regex might be something like (note: havn't checked it - especially the backslashes):
String regex="^\\s*if\\s+\\[\\s+\\\"\\$1\\\" = \\\""+config +"\\\" \\] ; then";
Before all else: leave out DataInputStream, more Java Object specific.
boolean started = false;
while ...
if (!started) {
started = strLine.matches("\\s*...\\s*");
} else {
...
Reg ex \\s* stand for zero or more white-space characters (tab, space).
I found a solution which i share with you .
public static HashMap<String, String> getEnvVariables(String scriptFile ,String config1,String config2) {
HashMap<String, String> vars = new HashMap<String, String>();
BufferedReader br = null;
try {
FileInputStream fstream = new FileInputStream(scriptFile);
br = new BufferedReader(new InputStreamReader(fstream));
String strLine = null;
String stopvar = config2;
String startvar =config1;
String keyword = "set";
do {
if (strLine != null && strLine.contains(startvar)) {
if (strLine.contains(stopvar)) {
return vars;
}
while (strLine != null && !strLine.contains(stopvar)) {
strLine = br.readLine();
if (strLine.trim().startsWith(keyword)&& !strLine.contains("$")) {
strLine = strLine.trim().substring(keyword.length())
.trim();
String[] split = strLine.split("=");
String name = split[0];
String value = split[1];
System.out.println(name + "=" + value);
vars.put(name, value);
}
}
}
} while ((strLine = br.readLine()) != null);
} catch (Exception e) {
Status status = new Status(Status.ERROR, Activator.PLUGIN_ID,
IStatus.ERROR, e.getMessage(), e);
Activator.getDefault().getLog().log(status);
}
return vars;
}
thanks for helping !