How to continuously read an online/web file in java? - java

I am making a simple text-only instant messenger in java. The way that it currently works is that all the messages are put into an online text file by sending a php file a request (I know this is bad for security, but this is just to learn how to do web-connected apps in java.)
Currently, I am continually fetching the entire contents of the messages.txt file and placing them into my JTextPane like this:
while(true) {
URL url = new URL("{path to text file}");
InputStream in = url.openStream();
Scanner s = new Scanner(in).useDelimiter("\\A");
String conversation = s.hasNext() ? s.next() : "";
textPane.setText(conversation);
}
But when the conversation becomes long enough, it lags as it is fetching 100kb+ files constantly from a web server.
What I want to happen is to only read the changes to the file so that it doesn't lag and max out my internet connection by requesting enourmous amounts of plain text files. I don't want to just make it run every 2 seconds because it's an instant messenger, no delays.
How would I go around only fetching the changes to the file and adding them to the text pane?

Can you push the file contents to another file once it crosses a certain threshold. This will ensure that you operate upon a smaller file.

Instead of contacting url directly you could place some server side script that would call the file
You could (as a client) provide the server script the last line / message identifier and the server could respond with new messages that have been added after the message id that the client has provided. In addition it could send the new last message id
With this approach the server side script doesnt even need to read itself the whole file and instead can immediately skip to the required line if message id contains the information about the line in the log file
Of course this approach is really far from real scenarios but its ok for learning IMO

Related

Java outputstream, trigger file download before all data retrieved from db

Im trying to wrap my head around Java Out/Inputstreams, closing and flushing. I have a situation where I want to create a file using Apache POI with data from a server. I would like the file to start downloading as soon as I retrieve the first record from the DB(Show the file at the bottom of the browser has started to download).
public void createExcelFile(final HttpServletResponse response,
final Long vendorId) {
try {
// setup responses types...
final XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
final XSSFSheet sheet = xssfWorkbook.createSheet("sheets1");
// create file with data
writeExcelOutputData(sheet, xssfWorkbook);
xssfWorkbook.write(response.getOutputStream());
xssfWorkbook.close();
}
catch (final Exception e) {
LOGGER.error("Boom");
}
The above code will perform a file download no problem, but this could be a big file. I go off getting the data(around 20/30s) and then after that the download begins < no good...
Can I achive what I need or whats the best approach, thanks in advance
Cheers :)
Reasons could be as following:
maybe there is a read/write timeout with your http server, then if the process gets lengthy or becasue of low-bandwidth, so the connection will be closed by the server.
make sure the process(the excel work) gets completely done, maybe there would be an error/exception during work.
The solution of Jorge looks very promising. User need once request for a file, then server would do the work in background and then either user check the work process and download the file if ready, or server informs the user by email, web notification, etc...
Also you would keep the file in the server in a temp file for a while, and if the connection gets interrupted, server would respond the generated file partial(omit the bytes sent, like normal file download)
Keeping a connection alive to do a lengthy work is not very logical.
Again, if the file gets ready fast(really fast) for download/stream, and the download interrupts, if could be becasue of read/write timeout by server, or a very bad network.

"Forwarding" an image upload with Java

I have a Web Service that receives an image upload by a Multipart POST request. I would like to forward the file to another web service without storing it, as the environment does not have access to a file system, so basically just passing along the information that's being received.
How do I achieve this?
If the other webservice resides on the same server use:
String url = "<relative path>";
request.getRequestDispatcher(url).forward(request, response);
return;
otherwise use:
response.sendRedirect(url);
You could always try chaining the input and output streams from one to the other, but I suspect you won't get very far with this when there's a hiccup on either side of the connection.
Another option you have, depending on how much memory you have access to, is to save it as a variable after you fetch it, and then pass it along to the other webservice. This of course won't work with very large images but it's a starting point.

Streaming audio and video from Android to PC/web.

I am recent beginner to Android SDK, and the overall goal of this project is to create an app very similar to Ustream's or Qik's (yeah, I know not the best idea for a beginner). I need to stream live audio and video to the web. There will be a video server, most likely using Wowza, handling the encoding of the videos to the proper format.
From what I have found so far, I need to use android's MediaRecorder with the camera as the source and direct the output to the server. That makes sense to me, but I do not know exactly how to go about doing that. Can anyone give me a push in the right direction? I have browsed through an example at "http://ipcamera-for-android.googlecode.com/svn/trunk", but that appears to be far more complicated than necessary for what I need to do and I have been unable to get it working in eclipse to test it anyway.
Doing so is not simple but possible.
The MediaRecorder API assumes that the output is a random access file, meaning, it can got forth and back for writing the mp4 (or other) file container.
As you can see in the ipcamera-for-android, the output file is directed to a socket which is not random access.
The fact makes it hard to parse the outgoing stream since the MediaRecorder API will "write" some data like fps, sps/pps (on h264) and so on only when the recording is done. The API will try to seek back to the beginning of the stream (where the file header exists) but it will fail since the stream is sent to a socket and not to a file.
Taking the ipcamera-for-android is a good reference, if I recall correctly, before streaming, it records a video to a file, opens the header and takes what it needs from there, than, it start recording to the socket and uses the data it took from the header in order to parse the stream.
You will also need some basic understanding in parsing mp4 (or other file container you'd want to use) in order to capture the frames.
You can do that either on the device or on the server side.
Here is a good start for writing the stream to a socket:
Tutorial
I hope it was helpful, there is no good tutorial for parsing and decoding the outgoing streams since it is not so simple...but again, it is possible with some effort.
Take a look also here to see how to direct the output stream to a stream that can be sent to the server:
MediaRecorder Question
SipDroid does exactly what you need.
It involves a hack to circumvent the limitation of the MediaRecorder class which require a file descriptor. It saves the result of the MediaRecorder video stream to a local socket (used as a kind of pipe), then re-read (in the same application but another thread) from this socket on the other end, create RTP packets out of the received data, and finally broadcast the RTP packets to the network (you can use here broadcast or unicast mode, as you wish).
Basically it boils down to the following (simplified code):
// Create a MediaRecorder
MediaRecorder mr = new MediaRecorder();
// (Initialize mr as usual)
// Create a LocalServerSocket
LocalServerSocket lss = new LocalServerSocket("foobar");
// Connect both end of this socket
LocalSocket sender = lss.accept();
LocalSocket receiver = new LocalSocket();
receiver.connect(new LocalSocketAddress("foobar"));
// Set the output of the MediaRecorder to the sender socket file descriptor
mr.setOutputFile(sender.getFileDescriptor());
// Start the video recording:
mr.start();
// Launch a background thread that will loop,
// reading from the receiver socket,
// and creating a RTP packet out of read data.
RtpSocket rtpSocket = new RtpSocket();
InputStream in = receiver.getInputStream();
while(true) {
fis.read(buffer, ...);
// Here some data manipulation on the received buffer ...
RtpPacket rtp = new RtpPacket(buffer, ...);
rtpSocket.send(rtpPacket);
}
The implementation of RtpPacket and RtpSocket classes (rather simple), and the exact code which manipulate the video stream content can be found in the SipDroid project (especially VideoCamera.java).

Save Java Applet Variable to Mysql

Hi
I've done a lot of research on the best way to communicate between a java applet and MySql Database.
I have a tune player which I have students logging onto, it's a java applet with a speed slider. I want to save the speed that they play each tune at so it goes back to the same speed the next time they open that tune.
It seems I have a number of options, none of which seem very neat.
Use a javascript function to
periodically check the speed and
save it to a cookie, then each page
of the site would have to check
cookies relationg to each tune.
Make each link on the page call a
javascript function to check the
speed variable in the applet and add
it to a perameter in the url then
redirect so the next php page can
save the speed to a database. This
way when the user navigates away the
speed will be saved, but this won;t
work if the back button is used.
Is there a better way of doing this?
Use the JNLP API and the problems should be solved.
Since Java 1.6.0_10+, it is possible to use the Java Web Start API services (JNLP API) within an embedded applet. The JNLP API provides the PersistenceService. Here is a small demo. of the PersistenceService.
If the user hits the back button (or otherwise leaves the page), the destroy() method will be called. Override the destroy method and persist the data at that time.
No need to use JavaScript.
The java code below posts variables to a PHP script on the web server then
shows the server response on the console
private void post()
throws MalformedURLException, IOException
{ URL url;
URLConnection con;
OutputStream oStream;
String parametersAsString;
byte[] parameterAsBytes;
String aLine; // only if reading response
parametersAsString = "msg=hi&to=memo";
parameterAsBytes = parametersAsString.getBytes();
// send parameters to server
url = this.getCodeBase();
url = new URL(url + "scriptfile.php");
con = url.openConnection();
con.setDoOutput(true);
// setDoInput(true); // only if reading response
con.setDoInput(false);
con.setRequestProperty("Content=length", String.valueOf(parameterAsBytes.length));
oStream = con.getOutputStream();
oStream.write(parameterAsBytes);
oStream.flush();
// read response from server & show the server response on the Java console or whatever ...
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
aLine = in.readLine();
while (aLine != null)
{ System.out.println(line);
aLine = in.readLine();
}
in.close();
oStream.close();
}
I'd suggest you get the applet to update the database. Whenever the speed slider changes you can fire off an update to the database, or you might need to coalesce multiple changes into one request depending on usage.
When the applet changes tune it can also do its own lookup of the correct speed.
Note that the applet will probably not be able to hit the database directly - browsers should restrict what I/O operations are available to applets - but you should be able to get the applet to hit a URL on the server that will actually perform the update. Signing the applet may let you hit the database but you should read up on the applet security model and the various browser quirks first.
It's not really clear how all of this is set up since you don't have a lot of details. However, assuming that you have an actual Java applet, I'd say the following:
If the Java applet requires a login (that is, it knows who the user is) then it can store the preference on the server. To do this you could have the applet connect to the server using JDBC, which isn't generally a good idea for internet-facing applets, or you could have the applet send a message to a server process such as a web server. That process connects to the mysql server.
The applet can communicate directly with the browser using Javascript. So you can have the applet set the cookie when the slider changes, instead of having the Javascript set it.

Image not deleted even if file.delete() method is called

I need to send an email along with an embedded image. Once the email has been sent, the image in the application server should be deleted immediately. The problem I'm facing is, after the email is sent, the control goes method which contain,
File file = new File("../bar.jpeg")
if(file.exists()){
file.delete();
System.out.println("Barcode Image Deleted");
}
It's printing "Barcode Image Deleted". But, the image is not deleted and is still present in the same location. I'm using multipart to attach the image to the email.
Why is it not getting deleted?
Are you using javax.mail?
If so, you'll need to wait till the mail has finished being sent, which you find out about by registering a TransportListener.
This also means you won't be able to use the static Transport.send() methods, but will have to construct and clean up your own session and transport.
I'm trying to remember details from a while ago... I think the DataHandler or DataSource don't close the input stream when they've finished reading it, so you need to keep a reference to it and close it yourself before you can delete the underlying file.
The File.delete method returns a boolean which indicates whether the deletion was successful.
It could be that the file deletion is not being successfully performed due to not having permissions to delete the file.
File.delete() returns a true/false condition. Try checking the return condition of delete to see if the system is actually reporting the file as deleted.
Firstly, File.delete() returns a boolean if it successfully deletes a file. Check that value and at least log it.
If it is not being deleted, then I would guess that either
the file is currently open for reading and the OS won't let you delete it until it is closed. Possible your mail software? My guess is that the mail software does not try to base64 encode the image (for inclusion in the message) until it is actually sending the message...and/or does not stop reading it until the mail is sent.
the java process does not have permissions to delete the file

Categories