can anyone tell me how to read multiple lines and store their value.
eg:file.txt
Probable Cause: The network operator has issued an alter attribute command for
the specified LCONF assign. The old value and the new value are show
Action Taken : The assign value is changed from the old value to the new
value. Receipt of this message does not guarantee that the new attribute
value was accepted by clients who use it. Additional messages may be.
Probable Cause: The network operator has issued an info attribute command for
the specified LCONF assign. The default value being used is displaye
Action Taken : None. Informational use only.
In the above file, Probable Cause and Action Taken are the column of a database table. And after Probable Cause: those are the value to be stored in the database table for probable cause column, same goes with action taken.
So how can i read the multiple lines and store their value? I have to read the value for probable cause until the line comes with Action Taken. I'm using BufferedReader and the readLine() method to read one line at a time. So can anyone tell me how to read directly from probable cause to action taken no matter how many line comes between them.
The simplest way is probably to just keep a List<String> for each value, with loops something like this:
private static final String ACTION_TAKEN_PREFIX = "Action Taken ";
...
String line;
while ((line = reader.readLine()) != null)
{
if (line.startsWith(ACTION_TAKEN_PREFIX))
{
actions.add(line.substring(ACTION_TAKEN_PREFIX))
// Keep reading the rest of the actions
break;
}
causes.add(line);
}
// Now handle the fact that either we've reached the end of the file, or we're
// reading the actions
Once you've got a "Probable Cause" / "Actions Taken" pair, convert the list of strings back to a single string, e.g. joining with "\n", and then insert in the database. (The Joiner class in Guava will make this easier.)
The tricky bit is dealing with anomalies:
What happens if you don't start with a Probable Cause?
What happens if one probable cause is followed by another, or one set of actions is followed by another?
What happens if you reach the end of the file after reading a probably cause but no list of actions?
I don't have the time to write out a complete solution now, but hopefully the above will help to get you going.
Related
I have a text file with entries like below.
{"id":"event1","state":"start","timestamp":"11025373"}
{"id":"event1","state":"end","timestamp":"11025373"}
{"id":"event2","state":"start","timestamp":"11025387"}
{"id":"event3","state":"start","timestamp":"11025388"}
{"id":"event3","state":"end","timestamp":"11025391"}
{"id":"event2","state":"end","timestamp":"11025397"}
I want to read the file as input and compare the time consumed by each event using Java. Like
event1 has taken (11025373 - 11025373) = 4ms time. (start - end)
event2 has taken (11025397 - 11025387) = 10ms time.
I initially thought to read line by line.
File file = new File("C:\\Users\\xyz\\inputfile.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null)
LOGGER.info(line);
Considering the input file size can be very Large is this the right approach?.
Any suggestion for best apporach will be helpful. And also how to compare each object in the file, i.e. compare "start" of event1 to "end" of event1 if I go line by line.
Considering the input file size can be very Large this is not not suitable I feel.
This is bizarre. It is, in fact, precisely the right approach. The wrong approach would be to read the entire thing in.
The only exception is if a single line can itself be truly humongous (let's say 128MB or up - that's.. a heck of a long line).
That is JSON format, you need a JSON reader. I suggest Jackson.
Make a class with the structure of that line, presumably something like:
enum State {
start, end;
}
class Event {
String id;
State state;
long timestamp;
}
Then, read a single line, ask Jackson to turn that line into an instance of Event, process it, and repeat until you're done with the file. This will let you process a file that is many GBs in size if you want, as long as any given line is not ridiculously long.
If a single line is ridiculously long: Well, JSON is not really designed for 'streaming', and most JSON libraries therefore don't do it, or at least don't make it easy. I therefore strongly suggest you don't attempt to write something that can 'stream' a single line unless you're sure you really need to do this.
The only slightly complicated thing here is that you need to remember the last read entry, so that you can update its 'time taken' property at that point, as you can only know that once you read the line after the right entry. This is basic programming though.
I am using the following code to produce a unique sequence of id numbers in a concurrent system:
String idNodePath = "/somenode/idNode";
Stat stat = null;
Integer id = null;
try{
stat = zk.setData(idNodePath, new byte[0], -1);
id = stat.getVersion();
} catch ( KeeperException e){
zk.create(idNodePath, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.getData(idNodePath, false, stat);
}
I am concerned that this may not be correct way to achieve this using Zookeeper, although I did find someone else using a similar approach here: http://permalink.gmane.org/gmane.comp.java.hadoop.zookeeper.user/3216 which give me a small amount of reassurance.
My question is: is this a safe thing to do in a concurrent system? Is there a guarantee that id numbers will be unique and sequential? (i.e. no gaps when all id numbers are put together from all concurrent processes/machines)
Update: Fix NullPointerException bug in code pointed out by AlexR (thanks!)
Your code definitely contains bug. Take a look on stat variable. It is null before try block and initialized there. But if KeeperException is thrown you arrive to the next line
int id = stat.getVersion();
that throws NullPointerException because stat is still null.
Now concerning the concurrency. As fat as I understand zk is a member of your class. In this case the code is incorrect too. Think about 2 threads. First evaluates line stat = zk.setData(), i.e. changes the state of zk. Second arrives to the same line and evaluates it too, i.e. changes the state of shared object zk according to its parameters. Then first thread calls zk.getVersion(), i.e. gets version according to the state that was set by thread 2.
I cannot give you any recommendations about changing your code because I do not know what would you like to achieve. If you can explain your task in details you will probably get better recommendation how to implement it.
I am currently trying to perform some regex on the result of a DatagramPacket.getData() call.
Implemented as String myString = new String(thepkt.getData()):
But weirdly, java is dropping the end quotation that it uses to encapsulate all data(see linked image below).
When I click the field in the variable inspector during a debug session and don't change anything, when I click off the variable field it corrects itself again without me changing anything. It even highlights the variable inspection field in yellow to signal change.
Its values are also displaying like it is still a byte array rather than a String object
http://i.imgur.com/8ZItsZI.png
It's throwing off my regex and I can't see anything that would cause it. It's a client server simulation and on the client side, the getData returns the data no problem.
I got it working by using the solution provided in:
https://stackoverflow.com/a/8557165/1700855
But I still don't understand how not specifying the length of the packet to the String constructor would cause it to drop the systematic end double quotes. Can anyone provide an explanation as I really like to understand solutions to my issues before moving on :)
The problem is that you didn't read the spec for DatagramPacket.getData:
Returns the data buffer. The data received or the data to be sent
starts from the offset in the buffer, and runs for length long.
So, to be correct, you should use
new String(thepkt.getData(), thepkt.getOffset(), thepht.getLength())
Or, to not use the default charset:
new String(thepkt.getData(), thepkt.getOffset(), thepht.getLength(), someCharset)
I have a java client server program that works fine on a half a dozen computere but is causing a NegativeArraySizeException on site.
This is the code
location = message.indexOf("last");
location += 5;
end = message.indexOf('&', location);
int size = end - location; THIS IS THE ERROR LINE
char[] lastC = new char[size];
message.getChars(location, location+size, lastC, 0);
String firstS = new String(firstC);
String lastS = new String(lastC);
message is an xml message I am reading.
location is an integer that points the the location of a character in the message, the first name in this case.
size is the length of the persons name.
As far as I can tell size is being set as a negative number and I don't know why.
Does anyone know how to fix this or a better was of finding the length of the name ?
This is part of the server side.
As far as I can tell size is being set as a negative number and I don't know why.
If the first call to indexOf cannot locate "last" in the message, then location will be set to -1 and then incremented by 5 to give 4.
If the second call to indexOf cannot find a '&' then end will be set to -1, and size will be negative.
Obviously, the input XML is not in the form you expect.
All in all, that code is pretty dodgy. As a minimum you should check the results of both calls to indexOf and take appropriate error reporting / recovery steps if they are -1.
But the real fix is to not attempt to "parse" XML using crufty string bashing. Use an XML parser, preferably with validation against the relevant schema or DTD. If the XML parser rejects the input, report the error back at who / whatever gave you the broken XML.
Does the message contain last at all? If not, location would be negative, and you should stop processing right there. This error might go unnoticed because you add 5 to location after that, which makes it equal to at least 4 even if last is not in the string (thanks SJuan76).
Even if the message contains last, is it guaranteed that it is followed by at least one extra character? If not, adding 5 to location would point outside the string for sure.
Moreover, end may also be negative if there is no & in the string after location. You should handle that somehow (i.e. by setting end to the length of the message in that case).
Also, if message is a string, you can simply extract a substring of it using the substring method, no need for the getChars magic.
A better solution would probably be something like this (I'm assuming that message is something like an URL and you are looking for the part between last> and the next &, based on your comment for one of the other answers):
location = message.indexOf("last>");
if (location >= 0) {
String lastS;
location += 5;
end = message.indexOf('&', location);
if (end == -1) {
// Handle the case when there is no "&" after "last>" in the message
} else {
lastS = message.substring(location, end);
}
} else {
// Handle the case when there is no "last>" in the message
}
The trouble is that end is less than location. The issue is what message are you expecting and which one you are receiving; the rest of the logic works for certain messages. Check from where you get your message String.
So I am making a URL request to fetch a stream of data into a BufferedReader. The data that I am fetching has values "null" for various fields. The while condition I am using to read all the data is:
while (((inputLine = in.readLine()) != null))
so the condition is breaking in between, when it encounters a null value, which is actually not the EOF but only a field value. How do I resolve this?
When you read a line, it will never be null until it reaches the end of the data. If there's no data in the line, it will just be an empty string instead.
You haven't shown enough code to explain why you're getting a NullPointerException, but you really need to understand that you won't see any "null values" before reaching the end of the data.
To work out why you're getting a NullPointerException:
Look at the line indicated in the stack trace
Identify every dereferencing operation
Either put a breakpoint on that line, or add some logging, or split the line into multiple statements so that each statement only has a single dereferencing operation
That should let you work out exactly which value is null, causing the exception to be thrown. What you need to do to fix it will depend on what you're trying to do and which value is null - we don't have enough information to help you on that front at the moment.