I am currently writing a java programm that fetches the source code from a html and parses it for a value. This works fine normally, but once I try to let it run in a while loop and refetch the data every 30 seconds my PC slows down until I stop the program manually.
while(true) {
try {
URL url = new URL("https://www.reddit.com/r/gaming/");
URLConnection urlConn = url.openConnection();
System.out.println(urlConn.getContentType()); //it returns text/html
BufferedReader in = new BufferedReader
(new InputStreamReader(urlConn.getInputStream()));
File test = new File("test");
BufferedWriter writer = new BufferedWriter(new FileWriter(test));
String text;
while ((text = in.readLine()) != null) {
writer.write (text);
}
writer.close();
in.close();
String content = new String(Files.readAllBytes(Paths.get("test")), "UTF-8");
Pattern pattern = Pattern.compile("title=(.*?)\">");
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
System.out.println(matcher.group(1));
if (Integer.valueOf((matcher.group(1))) <= 99999999) {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File("alert.wav"));
clip.open(inputStream);
clip.start();
}
}
Thread.sleep(30000);
} catch (MalformedURLException f) {
f.printStackTrace();
} catch (IOException f) {
f.printStackTrace();
} catch (InterruptedException f) {
f.printStackTrace();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
Any hints on why this is happening?
Maybe I'm misunderstanding the code, but I think that Thread.sleep() will only run if you don't throw. I think you want to put it outside of the try/catch so that if you fail, you wait 30 seconds before trying again. Otherwise, if something causes a throw, you will just retry again immediately and since nothing will have really changed since the last time you tried, you will immediately throw again over and over.
Right now, your code is:
while (true) {
try {
// Do a lot of things that can throw
if(something_bad_happens) throw new Error();
/*
* This sleep will only be reached
* if we don't throw
*/
Thread.sleep(30000);
} catch (errors) {
// Deal with errors
}
}
I think you actually want this:
while (true) {
try {
// Do a lot of things that can throw
if(something_bad_happens) throw new Error();
} catch (errors) {
// Deal with errors
}
// Always sleep between attempts no matter what
Thread.sleep(30000);
}
Related
Normally when I use
r = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream()));
then I use
int nextChar = 0;
while ((nextChar=r.read()) != -1)
{
}
Now I am going to use byte level
r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream()));
so the first byte I read is this
try {
while(true){
if (r.readByte() != 0x7E) // start byte
{
// ah oh, something went wrong!!
receivedSocketConn1.close();
return;
}
int bodyLen = r.readUnsignedShort(); // message body nature (body length)
byte serialNum1 = r.readByte();// message serial number
byte[] messageBody = new byte[20]; // message body
r.readFully(messageBody);
if (r.readByte() != 0x7E) // end byte
{
// ah oh, something went wrong!!
receivedSocketConn1.close();
return;
}
}
}
catch (SocketTimeoutException ex)
{
System.out.println("SocketTimeoutException has been caught");
ex.printStackTrace();
}
catch (IOException ex)
{
System.out.println("IOException has been caught");
ex.printStackTrace();
}
finally
{
try
{
if ( w != null )
{
w.close();
r.close();
receivedSocketConn1.close();
}
else
{
System.out.println("MyError:w is null in finally close");
}
}
}
You see it always goes into the finally block after I do the 7e, thereafter it cuts the link. I would like to keep the link for some time. But before that, I want to run a for loop for the look for the -1 in this scenario. How to I implement that?
You don't need to handle -1 in this situation.
If you read the documentation, it says:
InputStream::read()
Returns:
the next byte of data, or -1 if the end of the stream is reached.
DataInputStream::readByte()
Throws:
EOFException - if this input stream has reached the end.
IOException - the stream has been closed and the contained input stream does not support reading after close, or another I/O error occurs.
The same goes for all of the DataInputStream reading methods.
So, all you have to do is read values from the DataInputStream normally and let it throw an exception if the socket gets closed by the peer. You are already doing exactly that (EOFException extends IOException and will be caught in your catch (IOException ex) block). You are over-thinking the problem.
That being said, if reading the 0x7E byte is throwing an exception (which readByte() call is failing? Which exception is being thrown?), then you are doing something wrong. For instance, this question is based on code I gave you yesterday for another question, but the code you have shown in this question is incomplete based on the earlier code. That omission would easily cause the second if (r.readByte() != 0x7E) to evaluate as false and close the connection.
Try something more like this instead:
w = new DataOutputStream(new BufferedOutputStream(receivedSocketConn1.getOutputStream()));
r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream()));
try
{
while(true)
{
if (r.readByte() != 0x7E) // start byte
throw new RuntimeException("Incorrect start byte detected");
int messageID = r.readUnsignedShort(); // message ID
int bodyLen = r.readUnsignedShort(); // message body nature (body length)
byte[] phoneNum = new byte[6];
r.readFully(phoneNum); // device phone number
int serialNum = r.readUnsignedShort(); // message serial number
byte[] messageBody = new byte[bodyLen]; // message body
r.readFully(messageBody);
byte checkCode = r.readByte(); // check code
if (r.readByte() != 0x7E) // end byte
throw new RuntimeException("Incorrect end byte detected");
// TODO: validate checkCode if needed...
// ...
// if (checkCode is not valid)
// throw new RuntimeException("Bad checkCode value");
// process message data as needed...
}
}
catch (SocketTimeoutException ex)
{
System.out.println("SocketTimeoutException has been caught");
ex.printStackTrace();
}
catch (EOFException ex)
{
System.out.println("Socket has been closed");
}
catch (IOException ex)
{
System.out.println("IOException has been caught");
ex.printStackTrace();
}
catch (RuntimeException ex)
{
System.out.println(ex.getMessage());
ex.printStackTrace();
}
finally
{
w.close();
r.close();
receivedSocketConn1.close();
}
I want to load a loop objects to the list, but I have a problem, because the loop is performed only once and the next loop crashes IOException line 'movie = (Movie) ois.readObject () ;'.
#SuppressWarnings("unchecked")
static <T> void loadDatabase(List<T> tab, int index) {
if(index == 1) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("movies.ser"));
try {
while(true) {
Movie movie = new Movie();
movie = (Movie) ois.readObject();
tab.add((T) movie);
}
} catch(EOFException ignored) {
ois.close();
}
} catch (FileNotFoundException e) {
System.out.println("Can not find the file. Please try again later...");
} catch (IOException e) {
System.out.println("Unable to save file. Please try again later...");
} catch (ClassNotFoundException e) {
System.out.println("The error of the projection class Movie");
}
} else if(index == 2) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("series.ser"));
while(ois.available() != 0) {
Series series = new Series();
series = (Series) ois.readObject();
tab.add((T) series);
}
ois.close();
} catch (FileNotFoundException e) {
System.out.println("Can not find the file. Please try again later...");
} catch (IOException e) {
System.out.println("Unable to save file. Please try again later...");
} catch (ClassNotFoundException e) {
System.out.println("The error of the projection class Series");
}
}
}
Lets dissect your (sorry, but horrible, horrible) code a bit:
#SuppressWarnings("unchecked")
static <T> void loadDatabase(List<T> tab, int index) {
if(index == 1) {
Dont do that. The whole point of index seems to be to distinguish what this method should do. Hint: create two methods instead; and avoid that parameter, and the if!
One method you would call loadMovieFromDataBase(); the other loadSeriesFromDataBase().
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("movies.ser"));
try {
while(true) {
Do you really want to loop forever?! That is what while(true) will.
Well, not forever, but until some exception will be thrown. So, even when your loop body would be doing the right thing (which it isnt!) ... that code must lead into some error condition.
Movie movie = new Movie();
movie = (Movie) ois.readObject();
That is like absolute nonsense. There is no point in calling new on a Movie object to have then read by an ObjectInputStream.
Movie movie = (Movie) ois.readObject();
is how you deserialize an object from an ObjectInputStream.
tab.add((T) movie);
}
} catch(EOFException ignored) {
ois.close();
Hint: you are a beginner. You have no idea what your code is doing; but you feel confident enough to ignore exceptions; not even trace them?!
And the following catches are not much better:
} catch (FileNotFoundException e) {
System.out.println("Can not find the file. Please try again later...");
} catch (IOException e) {
System.out.println("Unable to save file. Please try again later...");
You try to read a file. Hint: be careful when doing copy&paste of ERROR messages. This one doesn't make any sense here. Beyond that: don't replace the exception with some self-defined message. At least print the exception message, too. Because: your own code is all lying.
} catch (ClassNotFoundException e) {
System.out.println("The error of the projection class Movie");
}
No, the above error would mean that you tried to deserialize a class which does not exist in the context of the JVM that this code is running it.
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("series.ser"));
while(ois.available() != 0) {
Series series = new Series();
series = (Series) ois.readObject();
Same story as above. And hint: don't query the stream if more input is there. Just serialize one list of Series objects; than you just de-serialize one object later on.
The reason why I spent my time here: it seems that you are blindly putting together code without the slightest idea what that code is doing. That is, well a bad idea.
You better step back and read & run good tutorials on serialization. And only when you are able to run and understand that part, you try to come up with your own code.
Actually it is bad idea. best is deserialization once, clone and add to list how many time u wants.
I put the declaration in the while loop, and the program would not running and also does not return any error. I suspect the while loop become an infinite loop.
try
{
while (true)
{
inputStream = new ObjectInputStream (new FileInputStream (fileName));
Ship copyObject = (Ship) inputStream.readObject();
String nameCompany = copyObject.getCompanyName();
if (compName.equalsIgnoreCase(nameCompany)){
listShipName += (copyObject.getShipName() + ", ");
numberOfShip ++;
}
}
}
catch (EOFException e)
{
}
catch (Exception e)
{
e.printStackTrace();
}
But if I put the declaration of input stream out of the while loop, the program runs successfully. Can someone explain why this happens?
try
{
inputStream = new ObjectInputStream (new FileInputStream (fileName));
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
while (true)
{
Ship copyObject = (Ship) inputStream.readObject();
String nameCompany = copyObject.getCompanyName();
if (compName.equalsIgnoreCase(nameCompany)){
listShipName += (copyObject.getShipName() + ", ");
numberOfShip ++;
}
}
}
catch (EOFException e)
{
}
catch (Exception e)
{
e.printStackTrace();
}
You're reopening your file on every iteration through the loop, which means you are only ever reading the first object from the file. But you're reading the same object over and over again.
As well as opening your file only once, you really should try to detect the end of file without throwing an exception. As a matter of style, exceptions should be thrown when things go wrong, not as a matter of course.
Now I realize that in each iteration, I reopen the input stream, so the loop would not reach to the end of the file, and it becomes infinite.
I am running another jar with this code:
(I am updating a gui in some parts , so dont feel confused.)I get an IO Exception (Stream Closed) here:
if((line = readr.readLine()) != null){
Thats the full code:
if(!data.serverStarted()){
try{
data.updateConsole("Starting server!");
String fileDir = data.dir + File.separator + "craftbukkit.jar";
Process proc = Runtime.getRuntime().exec("java -Xmx2048M -jar "+"craftbukkit.jar"+" -o true --nojline");
data.setOutputStream(proc.getOutputStream());
InputStream is = proc.getErrorStream();
}catch(IOException ex){
ex.printStackTrace();
}
BufferedReader readr = new BufferedReader(new InputStreamReader(is));
data.setServerStarted(true);
String line;
while(data.serverStarted()){
try {
if((line = readr.readLine()) != null){
data.updateConsole(line);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
readr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}else{
data.updateConsole("You have already started your server!");
}
You have a while loop that closes readr on every pass. The next time it gets to the try block, readr is closed. Perhaps you intended to put the try/catch block around the while loop?
You are closing the reader inside the loop that reads from it. You need to close it outside of the loop:
try {
String line;
while (data.serverStarted() && ((line = readr.readLine()) != null)) {
try {
data.updateConsole(line);
} catch (IOException e) {
e.printStackTrace();
}
}
} finally {
try {
readr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I am surprised that this code even compiles.
You declare the actual InputStream is inside the try/catch at the beginning, but that makes it only visible inside that block. So whatever you give to the BufferedReader a few lines below is something else and most likely not what you think it is.
In addition your while(data.serverStarted()) does not check if the stream is still open, and later you only use a single if check (again with no check if the stream is open), so you'll only read one single line at best.
I have a feeling that you had a bad OutOfCoffeeException while writing this code. ;)
We have java socket connection application which receives data from gps devices. The problem now at times we received corrupted data and checked on the device logs everything is fine. First BufferedReader was used and suspected to be the culprit. The we moved to inpustream also still having problem. The corruption is at random and not fixed interval. Below is the snippet of codes.
public void run() {
String completeMessage="";
//BufferedReader readerBuffer = null;
InputStream is = null;
BufferedWriter writeBuffer = null;
try {
//readerBuffer = new BufferedReader(new InputStreamReader(sockConn1.getInputStream()));
is = sockConn1.getInputStream();
writeBuffer = new BufferedWriter(new OutputStreamWriter(sockConn1.getOutputStream()));
int readChar=0;
sockConn1.setSoTimeout(120000);
//dbConnection = connectionPool.getConnection();
//dbConnection.setAutoCommit(false);
int readChar
while ((readChar=is.read()) != -1)
{
System.out.println("Char value: "+(char)readChar) ;
if (readChar == '*') {
try {
//writeBuffer.write("##\r\n\r\n");
//writeBuffer.flush();
//db processing
dbConnection.commit();
}
catch (SQLException ex){
ex.printStackTrace();
try{
dbConnection.rollback();
}
catch (Exception rollback){
rollback.printStackTrace();
}
}
catch (Exception e){
e.printStackTrace(System.out);
try{
dbConnection.rollback();
}
catch (Exception rollback){
rollback.printStackTrace(System.out);
}
}
finally{
try{
if ( dbStmt != null ){
dbStmt.close();
}
}
catch(SQLException ex){
ex.printStackTrace(System.out);
}
}
completeMessage="";
}
}
}
catch (SocketTimeoutException ex){
ex.printStackTrace();
}
catch (IOException ex){
ex.printStackTrace();
}
catch (Exception ex){
ex.printStackTrace();
}
finally{
try{
if ( dbConnection != null ){
dbConnection.close();
}
}
catch(SQLException ex){
ex.printStackTrace();
}
try{
if ( writeBuffer != null ){
writeBuffer.close();
}
}
catch(IOException ex){
ex.printStackTrace(System.out);
}
}
}
There is a problem. You read/write binary data as text:
InputStream, OutputStream = binary data
Reader, Writer = text
This is bridged by:
new InputStremReader(inputStream, charEncoding)
new OutputStreamWriter(outputStream, charEncoding)
And String to byte is bridged by:
new String(bytes, charEncoding)
string.getBygtes(charEncoding)
Where charEncoding is an optional parameter, defaulting to the operation system encoding.
With UTF-8, the Unicode multi-byte encoding, you are fast into troubles if done wrong. Also other encodings have problematic bytes.
So do not use Reader/Writer.
The read() delivers an int, -1 for end-of-file, a byte value otherwise.
It seems your test with read() throws a byte away, and the subsequent read does not test for -1.
It is not clear what character encoding is used here.
When you deal with character streams then it is nearly always a good idea to explicitly provide the character encoding to en-/decode the byte stream.
In my opinion it is most likely a character encoding issue here. Use the same encoding on both sides and you won't have trouble with Reader/Writer.