How to append text into text file dynamically [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
[12]
key1=val1
key2=val2
key3=val3
key4=val4
key5=val5
[13]
key1=val1
key2=val2
key3=val3
key4=val4
key5=xyz
[14]
key1=val1
key2=val2
key3=val3
key4=val4
key5=val5
I want to update key5=val5 where [13].
try {
br = new BufferedReader(new FileReader(oldFileName));
bw = new BufferedWriter(new FileWriter(tmpFileName));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if (line.contains("[13]"))
{
while (line.contains("key5")) {
if (line.contains("key5"))
{
line = line.replace("key5", "key5= Val5");
bw.write(line+"\n");
}
}
}
}
} catch (Exception e) {
return;
} finally {
try {
if(br != null)
br.close();
} catch (IOException e) {
//
}
try {
if(bw != null)
bw.close();
} catch (IOException e) {
//
}
}

This block of code is problematic:
if (line.contains("[13]"))
{
while (line.contains("key5")) {
//etc....
Because there are NO lines which contain both [13] and key5 (they are on separate lines), so the while loop will NEVER be entered.
Instead, when the line [13] is encountered, it's necessary to remember it and store the flag in a boolean, something like the following:
boolean in13 = false;
//... other lines...
if (line.equals("[13]")) {
in13 = true;
} else if (line.startsWith("[")) {
in13 = false; //another block started, clear flag
}
if (in13 && line.startsWith("key5=")) {
// you've found it
}

You really need to step through your logic in your head; in your code:
if (line.contains("[13]")) {
while (line.contains("key5")) {
if (line.contains("key5")) {
line = line.replace("key5", "key5= Val5");
bw.write(line+"\n");
}
}
}
Try writing this out on a piece of paper or something and following it. Look at your while (line.contains("key5")) loop for example. If the line contains "[13]" then it does not contain "key5" and your loop does not even run once. There are many other problems as well (such as the fact that you're only attempting to write one line back out, as another person mentioned in the comments, or that you're not reading any more lines inside your loop, among other issues). For these types of things, work out precisely what you want to do, then write code to match. It looks like you want to do the following:
Search for the line "[13]". Once found...
Search for a line starting with "key5=", but stop when a new section (starting with "[") is encountered. If that is found:
Replace that line with "key5=" + new value.
And for each line you touch that you do not replace, you'd have to write it back out (although a general formula here, barring memory constraints, is to parse/load, then modify, then write).
So you'll want your code to do that.
Also note that some INI file parser implementations (presuming you are treating this as an INI file) ignore whitespace and/or case in the key and section names, so depending on the source of your file, you may want to take that into account.
By the way, perhaps consider using an INI file handling library such as ini4j, where you can load the file and replace keys directly. See What is the easiest way to parse an INI file in Java?.

This part looks wrong:
while (line.contains("key5")) {
if (line.contains("key5"))
I assume that NOT operator is missing in loop condition

Related

OutputStreamWriter only writing one item into file

I have used the following code to write elements from an arraylist into a file, to be retrieved later on using StringTokenizer. It works perfect for 3 other arraylists but somehow for this particular one, it throws an exception when reading with .nextToken() and further troubleshooting with .countTokens() shows that it only has 1 token in the file. The delimiters for both write and read are the same - "," as per the other arraylists as well.
I'm puzzled why it doesnt work the way it should as with the other arrays when I have not changed the code structure.
=================Writing to file==================
public static void copy_TimeZonestoFile(ArrayList<AL_TimeZone> timezones, Context context){
try {
FileOutputStream fileOutputStream = context.openFileOutput("TimeZones.dat",Context.MODE_PRIVATE);
OutputStreamWriter writerFile = new OutputStreamWriter(fileOutputStream);
int TZsize = timezones.size();
for (int i = 0; i < TZsize; i++) {
writerFile.write(
timezones.get(i).getRegion() + "," +
timezones.get(i).getOffset() + "\n"
);
}
writerFile.flush();
writerFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
==========Reading from file (nested in thread/runnable combo)===========
public void run() {
if (fileTimeZones.exists()){
System.out.println("Timezone file exists. Loading.. File size is : " + fileTimeZones.length());
try{
savedTimeZoneList.clear();
BufferedReader reader = new BufferedReader(new InputStreamReader(openFileInput("TimeZones.dat")));
String lineFromTZfile = reader.readLine();
while (lineFromTZfile != null ){
StringTokenizer token = new StringTokenizer(lineFromTZfile,",");
AL_TimeZone timeZone = new AL_TimeZone(token.nextToken(),
token.nextToken());
savedTimeZoneList.add(timeZone);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
}
===================Trace======================
I/System.out: Timezone file exists. Loading.. File size is : 12373
W/System.err: java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at com.cryptotrac.trackerService$1R_loadTimeZones.run(trackerService.java:215)
W/System.err: at java.lang.Thread.run(Thread.java:764)
It appears that this line of your code is causing the java.util.NoSuchElementException to be thrown.
AL_TimeZone timeZone = new AL_TimeZone(token.nextToken(), token.nextToken());
That probably means that at least one of the lines in file TimeZones.dat does not contain precisely two strings separated by a single comma.
This can be easily checked by making sure that the line that you read from the file is a valid line before you try to parse it.
Using method split, of class java.lang.String, is preferable to using StringTokenizer. Indeed the javadoc of class StringTokenizer states the following.
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
Try the following.
String lineFromTZfile = reader.readLine();
while (lineFromTZfile != null ){
String[] tokens = lineFromTZfile.split(",");
if (tokens.length == 2) {
// valid line, proceed to handle it
}
else {
// optionally handle an invalid line - maybe write it to the app log
}
lineFromTZfile = reader.readLine(); // Read next line in file.
}
There are probably multiple things wrong, because I'd actually expect you to run into an infinite loop, because you are only reading the first line of the file and then repeatedly parse it.
You should check following things:
Make sure that you are writing the file correctly. What does the written file exactly contain? Are there new lines at the end of each line?
Make sure that the data written (in this case, "region" and "offset") never contain a comma, otherwise parsing will break. I expect that there is a very good chance that "region" contains a comma.
When reading files you always need to assume that the file (format) is broken. For example, assume that readLine will return an empty line or something that contains more or less than one comma.

Java NullPointerException in reading [duplicate]

This question already has answers here:
Using BufferedReader.readLine() in a while loop properly
(7 answers)
Closed 8 years ago.
I have problem with reading from my socket i read only if value isn't null but it doesnt't works.
#Override
public void run() {
System.out.println("Reading from socket");
while(true){
try {
if(!(br.readLine().equals(null)))read += br.readLine();
} catch (IOException e) {
System.out.println("error " + e);
}
}
}
here is error:
Exception in thread "Thread-4" java.lang.NullPointerException
at connection.CreateConnection.run(CreateConnection.java:61)
at java.lang.Thread.run(Unknown Source)
If br.readLine() returns null, then calling .equals(null) on it will throw an exception - it won't return true. You just want to compare reference identity with null.
Calling .equals(null) is never useful, unless you're testing that your equals implementation works properly :)
Additionally, you'll be skipping every other line by calling readLine() twice on each loop iteration.
You want something like:
String line;
if ((line = br.readLine()) != null) {
read += line;
}
... except that will be painfully slow due to repeated string concatenation. You should almost certainly be using a StringBuilder instead.
Also, doing all of this in a loop which catches IOException seems like a recipe for disaster - if the a call fails, it's very likely that it'll keep failing forever, whereupon your program is basically hung in a tight loop. You should almost certainly stop when you get an exception, rather than keeping going. For example:
try {
String line;
while ((line = reader.readLine()) != null) {
read += line; // Or builder.append(line);
}
} catch (IOException e) {
// Whatever you want to do
}
Finally, consider the value of whitespace, both horizontal and vertical, as well as the benefits of using braces even in single-statement if statements etc. The line if(!(br.readLine().equals(null)))read += br.readLine(); is compact at the expense of readability.
Say you are on the last line of your file, you call br.readLine() to check if it's not null. Your line exists so your test passes. Then you call br.readLine() once again. Unfortunately there is nothing left to read! And you get your exception.
Rewrite your code like that:
#Override
public void run() {
System.out.println("Reading from socket");
String line;
while(true){
try {
line = br.readLine()
if((line != null))read += line;
} catch (IOException e) {
System.out.println("error " + e);
}
}
}
You are calling .equals() on a null object, which causes the null pointer issue I assume. If you want to read with a buffered reader, try doing something like:
String line = reader.readLine();
while(line != null){
System.out.println(line);
line = reader.readLine();
}
This will eliminate the issue of null pointers, and will also stop you from skipping any lines during reading.

Best method to write objects to a text file [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I want to know what would be the best way to save objects to a file ? Saving in the sense, the objects need to be appended.
When i searched the internet i found that printwriter saves an object in the format of it's toString method, but then if it saves an object to a file in the toString format , how can the programer use it to access an instance in an object.
What i mean is, if i save a student object to a text file using printwriter(The object has a name, id and age) , how can i use it in the future to compare the age of one student with another student's age / search by id , etc.
Since the object is saved as a string , it can only be read as a string so how can i access the instances of an object?
The other method i found out is serialization. Serialization looks like it does the job but then i found out that it cannot append objects to a file , because it's stream header keeps on overriding. Is there a method to append objects to a file using serialization ?
Currently these are the only 2 methods i found out for writing objects , but it seems i cannot use any of these methods since when saved using printwriter , it will be read as a string and if i use serialization i can store only one record.
Thank you for your time.
JAXB will be great choice for you, as I see from your problem description. Here is a simple example to start with.
JAXB is a part of standard JDK since 1.6, so you don't need any additional libraries.
Also is supports collections serialization so you can easily implement your "append" task.
What could be a good idea (in my opinion at least) is to use XStream to serialize entire objects to file as XML. Using that library you could serialize entire objects to store them and then use that same library to automatically convert the XML back to the objects so that you can compare them.
Also, saving stuff to File as XML will allow other languages to be able to process the same file.
Why not use FileOutputStream instead of PrintWriter and simply write the data to a file in append mode? FileOutputStream does have a append mode constructor.
Java Serialization example
FileOutputStream Javadoc
How about you override writeStreamHeader and reset?
ObjectOutputStream ooStream = null;
try{
ooStream = new ObjectOutputStream(new FileOutputStream("object-writer"));
ooStream.writeObject(new ObjectWriter());
} catch(Exception ex){
ex.printStackTrace();
} finally {
if(ooStream != null){
try {
ooStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ObjectOutputStream ooStream2 = null;
try{
ooStream2 = new ObjectOutputStream(new FileOutputStream("object-writer", true)) {
#Override
public void writeStreamHeader() throws IOException {
reset();
}
};
ooStream2.writeObject(new ObjectWriter());
} catch(Exception ex){
ex.printStackTrace();
} finally {
if(ooStream2 != null){
try {
ooStream2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ObjectInputStream oiStream = null;
try {
oiStream = new ObjectInputStream(new FileInputStream("object-writer"));
System.out.println(oiStream.readObject());
System.out.println(oiStream.readObject());
} catch (Exception e) {
e.printStackTrace();
} finally {
if(oiStream != null){
try {
oiStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

BufferedReader.readLine doeasn't start from the file beginning and skips lines

I need to read a text file line by line till I find a specific string. I'm using BufferedReader.readLine() but when I debug I find that it starts from the third line in the file and skips lines after that.
Here is my code:
try {
reader = new BufferedReader(new FileReader(path));
String line1 = null;
while ((line1 = reader.readLine()) != null) {
if (line1.toString() == invocation0) {
found = true;
return false;
} else if (line1 == invocation1) {
found = true;
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {
}
}
I would really appreciate any help, as I tried many different solutions for this and still can't solve this issue.
the content of the file is like:
.//============================================================================
.// File: abc.mark
.// Description: anything
.// Notice: anything
.// .//============================================================================
.invoke RemoveClass("Properties",0)
if(line1.equals(invocation0))
Use equals() method for String value comparison.
Also, instead of return within the if, you can use a break. This is just a suggestion though.
BufferedReader should not be skipping the anything. Unfortunately you are the one who is making read method to skip the line. The equlaity operator == will not compare the content of any two strings, rather it compares whether they are of same object. You could possibly avoid it in two ways.
Call the intern() on invocation0 (line1 object should have been interned before anyway)
More precisely use equals method line1.equals(invocaton0)
This link may be of some help for you to understand it better.

Is it possible to use Java SE to enter text on a line?

I'd like to know if there's a way where the Java SE allows a passage to be printed out and then in between the line we can allow the user to type the answer on the line.
To be more clear :
Here's an example:
____ reading, Alice also enjoys listening to classical music.
So, when the text is being drawn out using the buffer reader, the user is able to enter the answer on the line itself.
Here's the method of buffer reader:
public void getCloze(){
File file = new File("cloze.txt");
StringBuffer contents = new StringBuffer();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String text = null;
// repeat until all lines is read
while ((text = reader.readLine()) != null) {
contents.append(text)
.append(System.getProperty(
"line.separator"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
// show file contents here
System.out.println(contents.toString());
}}
Hope someone can advise me how to and best if there's any tutorial to show the steps.
I dont think it is possible to prompt the user to type in between the already printed line in Java. you have to stop your priniting to take user input and then print further string to the user
It is not entirely clear what your problem is, but you seem to want to know how to write a question or prompt and allow the user to enter the answer on the same line. If so, the "trick" is to use System.out.print(prompt) rather than System.out.println(prompt); i.e. DON'T output a line break after the prompt.
UPDATE - I see what you are asking now.
Well the bad news is that there is no simple way to do that. However, it is doable using something like the charva library or a "curses for Java" library - What's a good Java, curses-like, library for terminal applications?

Categories

Resources