file caching

B

bitshit

Hi all,

I noticed that when I download a file with a.class extension over a
urlconnection, the jre will automatically cache it in the jpi_cache (if
setUseCache(true) is set for the urlconnection).

But if I set UseCache to true I cannot read progress it makes downloading it
(see source), probably because the jre uses an internal mechanism when it
detects an connection to a .class extension.

If i set setUseCache(false) it will print the progress like it should, but
then it won't get cached...

Is anyone aware of a workaround for this problem? I like to have the files I
download get cached (saves me bandwidth, startup time etc). But on the other
hand I want to show the progress to the user (especially with large files).

Is there any other method that triggers the jvm into caching a file?
Prefferably after i've downloaded the content in a byte array with
setUseCache(false). I'm not using a signed applet, so classloaders are no
option :(


SOURCE:

import java.io.*;
import java.net.*;
import java.applet.Applet;

public class Test extends Applet implements Runnable
{
public static boolean cache=false;
public static String url="http://localhost/testfile.class";

public void init()
{
try
{
if(getParameter("cache").equals("true")) cache=true;
if(getParameter("url").length()>0) url=getParameter("url");

}
catch(Exception e)
{
e.printStackTrace();
}

new Thread(this).start();
}

public void run()
{
new Thread(new Download()).start();
}

class Download implements Runnable
{
public void run()
{
try
{
URL url = new URL(Test.url);
URLConnection c = url.openConnection();
c.setUseCaches(Test.cache);
int headerfield_contentlength = c.getContentLength();

System.out.println("getInputStream, with setUseCache(true) it downloads the
whole stream before we can do anything");
InputStream f = c.getInputStream();
System.out.println("getInputStream returned");

BufferedInputStream bis = new BufferedInputStream(f);

//if no contentlenght header was set, allocate a temp buffer of 4mb
if(headerfield_contentlength<=0)
{
headerfield_contentlength=4*1024*1024;
}

byte[] byteData = new byte[headerfield_contentlength];
int realLength=0, bytesRead;

int length=bis.available();
byte[] tmpBuff=new byte[length];

//read max blocks of 5kb to force frequent download updates
if(length>5120) length=5120;

System.out.println("Downloading...");

//read in bytes from the stream & update the progresslistener if available
while((bytesRead = bis.read(tmpBuff,0,length)) != -1)
{
System.arraycopy(tmpBuff, 0, byteData, realLength, bytesRead);
realLength+=bytesRead;
System.out.println("read "+bytesRead+" bytes of data...");
}

//if the contentlenght was unknown, copy only the data needed
if(realLength<byteData.length)
{
tmpBuff = new byte[realLength];
System.arraycopy(byteData, 0, tmpBuff, 0, realLength);
byteData = tmpBuff;
}

System.out.println("Done.");

bis.close();
f.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}


test html (see the difference in downloading by setting cache to "true" or
"false", the url

should point to a file with a .class extension):

<HTML>
<BODY BGCOLOR="#000000" TEXT="#DDEECC" LINK="#FF8899" VLINK="#9988FF"
ALINK="#FFFFFF">
<CENTER>
<p>
<APPLET codebase="http://localhost" code="Test.class" width="10" height="10"
name="Test">
<param name="cache" value="true"></param>
<param name="url" value="http://localhost/testfile.class"></param>
</APPLET>
</p>
</CENTER>
</HTML>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,202
Latest member
MikoOslo

Latest Threads

Top