Can someone please give me a hand with this image downloading code? I want it to run in the background, but it seems like new Thread(new Runnable()) is definitely not the way to go, according to the Android docs, and I'm not sure how else to approach this:
// caller
while( exhibitorCursor.moveToNext() )
{
new Thread(new Runnable()
{
public void run()
{
downloadImage(exhibitorId, exhibitorString, DOWNLOAD_EXHIBITOR);
}
}).start();
}
// first function
public void downloadImage(long id, String externalImageUrl, int type)
{
// logic junk here
if( !(new File(localImageName).exists()) )
{
DownloadFromUrl(externalImageUrl, localImageName);
}
}
// second function
public void DownloadFromUrl(String fileUrl, String fileName)
{
// this is the downloader method
try
{
URL url = new URL(fileUrl);
File file = new File(fileName);
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is, 8192);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while( (current = bis.read()) != -1 )
{
baf.append((byte)current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.close();
}
catch( IOException e )
{
Log.d("ImageManager", "Error: " + e);
}
}
Is there a less painful way of doing this? I'm only downloading like 20 images to use later in the app, and it is locking it up right away.
It may not be relevant, but this is how I am achieving it in Obj-C for the iPhone version.
for( NSDictionary *exhibitor in exhibitors )
{
[self performSelectorInBackground:#selector(downloadExhibitorImage:) withObject:exhibitor];
}
Take a look at the DownloadManager and as an alternative at AsyncTask
Related
I am trying to create FTP using TCP/IP in Java. Everything works fine in IDE, but then I decided to make it an IDE independent application by introducing GUI. In order to update GUI I implemented SwingWorker. Here is the code for my Client.java where the problem arises. Transfer gets successful but Stream is not flushed and the connection is not closed due to which the file gets corrupted. Also, GUI doesn't get updated.
Receive Method
public void receive()throws Exception
{
String ipadd = ipaddress.getText();
String port1 = socketname.getText();
String filepath = directory.getText();
String filepath1 = filepath.replaceAll("\\\\", "/");
String filename1 = name.getText();
String finalpath = filepath1+"/"+filename1;
int port = Integer.parseInt(port1);
Socket s = new Socket(ipadd,port);
byte[] contents = new byte[10000];
File file = new File(finalpath);
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataInputStream is = new DataInputStream(s.getInputStream());
long fileLength = is.readLong();
while((bytesRead = is.read(contents))!=1) {
SwingWorker<Void,Integer> worker = new SwingWorker<Void,Integer>() {
#Override
protected Void doInBackground() throws Exception {
totalbytesread+= bytesRead;
bos.write(contents, 0 ,bytesRead);
publish(totalbytesread);
return null;
}
#Override
protected void process(List<Integer> chunks) {
int value = chunks.get(chunks.size() - 1);
System.out.println(value);
progress.setText("Received "+(value/1000000)+" MB out
of "+(fileLength/1000000)+" MB.......("+
(value*100)/fileLength+"%)");
super.process(chunks);
}
#Override
protected void done() {
progress.setText("File Received!!");
super.done();
}
};worker.execute();
}
bos.flush();
s.close();
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(null, "File Successfully Received!!");
}
Please help..
I am starting with a response from a HTTP request:
InputStream responseInputStream = response.getEntityInputStream()
I need to gzip that response so I can upload it to s3 and save it compressed:
this.s3.putObject(new PutObjectRequest(bucketName, key, gzippedResponseInputStream, meta));
I am aware that I can get the byte[] array out of responseInputStream and then gzip them into a new InputStream. However, that can be very inefficient with a large amount of data.
I know that there have been similar questions asked on SO, but I have not found anything that seems to address the specific need of starting with an InputStream and finishing with a gzipped InputStream.
Thanks for any help!
I think you're looking for a PipedInputStream
Here's how it can be done.
public InputStrema getGZipStream() {
final PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream();
try (final InputStream responseInputStream = response.getEntityInputStream();
){
pis.connect(pos);
Thread thread = new Thread() {
public void run () {
startWriting(pos, responseInputStream);
}
};
thread.start();
} catch(Exception e) {
e.printStackTrace();
}
return pis;
}
public void startWriting(OutputStream out, InputStream in) {
try (GZIPOutputStream gOut = GZIPOutputStream(out);) {
byte[] buffer = new byte[10240];
int len = -1;
while ((len = in.read(buffer)) != -1) {
gOut.write(buffer, 0, len);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
out.close();
} catch( Exception e) {
e.printStackTrace();
}
}
}
I haven't tested this code, please let me know if this works.
public final class Example {
public static void main(String[] args) throws IOException, InterruptedException {
final PipedInputStream inputStream = new PipedInputStream();
final PipedOutputStream outputStream = new PipedOutputStream(inputStream);
Thread compressorThread = new Thread() {
#Override
public void run() {
try (FileInputStream dataSource = new FileInputStream(args[0])) {
try (GZIPOutputStream sink = new GZIPOutputStream(outputStream)) {
final byte[] buffer = new byte[8 * 1024];
for (int bytesRead = dataSource.read(buffer); bytesRead >= 0; bytesRead = dataSource.read(buffer)) {
sink.write(buffer, 0, bytesRead);
}
}
} catch (IOException ex) {
//TODO handle exception -> maybe use callable + executor
}
}
};
compressorThread.start();
try (FileOutputStream destination = new FileOutputStream(args[1])) {
final byte[] buffer = new byte[8 * 1024];
for (int bytesRead = inputStream.read(buffer); bytesRead >= 0; bytesRead = inputStream.read(buffer)) {
destination.write(buffer, 0, bytesRead);
}
}
compressorThread.join();
}
}
You are right, my previous example was wrong. You can use piped streams. The catch here is that you cannot use the input and output stream from the same thread. Also don't forget to join() on the writing thread. You can test my example by supplyng two parameters:
args[0] -> the source file
args[1] -> the destination to write the compressed content
PS: #11thdimension was a few minutes faster with his piped stream solutions, so if you find this helpful please accept his answer
I have a URL i.e http://downloadplugins.verify.com/Windows/SubAngle.exe .
If I paste it on the tab and press enter then the file (SubAngle.exe) is getting downloaded and saved in the download folder. This is a manual process. But it can be done with java code.
I wrote the code for getting the absolute path with the help of the file name i.e SubAngle.exe.
Requirement:- With the help of the URL file gets downloaded,Verify the file has been downloaded and returns the absolute path of the file.
where locfile is "http://downloadplugins.verify.com/Windows/SubAngle.exe"
public String downloadAndVerifyFile(String locfile) {
File fileLocation = new File(locfile);
File fileLocation1 = new File(fileLocation.getName());
String fileLocationPath = null;
if(fileLocation.exists()){
fileLocationPath = fileLocation1.getAbsolutePath();
}
else{
throw new FileNotFoundException("File with name "+locFile+" may not exits at the location");
}
return fileLocationPath;
}
easy and general function that im using:
import org.apache.commons.io.FileUtils;
public static void downLoadFile(String fromFile, String toFile) throws MalformedURLException, IOException {
try {
FileUtils.copyURLToFile(new URL(fromFile), new File(toFile), 60000, 60000);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("exception on: downLoadFile() function: " + e.getMessage());
}
}
Instead of writing this huge code, go for Apache's commons.io
Try this:
URL ipURL = new URL("inputURL");
File opFile = new File("outputFile");
FileUtils.copyURLToFile(ipURL, opFile);
Code to DownloadFile from URL
import java.net.*;
import java.io.*;
public class DownloadFile {
public static void main(String[] args) throws IOException {
InputStream in = null;
FileOutputStream out = null;
try {
// URL("http://downloadplugins.verify.com/Windows/SubAngle.exe");
System.out.println("Starting download");
long t1 = System.currentTimeMillis();
URL url = new URL(args[0]);
// Open the input and out files for the streams
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
in = conn.getInputStream();
out = new FileOutputStream("YourFile.exe");
// Read data into buffer and then write to the output file
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
long t2 = System.currentTimeMillis();
System.out.println("Time for download & save file in millis:"+(t2-t1));
} catch (Exception e) {
// Display or throw the error
System.out.println("Erorr while execting the program: "
+ e.getMessage());
} finally {
// Close the resources correctly
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
Configure the value of fileName properly to know where the file is getting stored.
Source: http://www.devmanuals.com/tutorials/java/corejava/files/java-read-large-file-efficiently.html
The source was modified to replace local file with http URL
Output:
java DownloadFile http://download.springsource.com/release/TOOLS/update/3.7.1.RELEASE/e4.5/springsource-tool-suite-3.7.1.RELEASE-e4.5.1-updatesite.zip
Starting download
Time for download & save file in millis:100184
i write simple applet to download file from HTTP URL.
In Eclipse or Netbeans, it 's work well and can download file to d://abc//123.iso on my HDD.
This is my code :
public class download {
public static void saveUrl(final String filename, final String urlString)
throws MalformedURLException, IOException {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
in = new BufferedInputStream(new URL(urlString).openStream());
fout = new FileOutputStream(filename,true);
final byte data[] = new byte[1024];
int count;
fout.write(data, 0, count);
} finally {
if (in != null) {
in.close();
}
if (fout != null) {
fout.close();
}
}
}
}
public class HelloWorldApplet extends Applet
{
public void paint (Graphics g)
{
g.drawString ("Download file", 25, 50);
String url ="http://downloads.asterisk.org/pub/telephony/asterisk-now/AsteriskNOW-612-current-32.iso";
String file_out = "d:\\abc\\123.iso";
download.saveUrl(file_out, url);
}
}
==========================
But when export to jar file and run with html, browser can creat new file 123.iso on my HDD but the size of this file is always 2 Kbps. i think it do not download anything.
Please help me
Thanks so much
P/s : i try to sign jar file with jarsigner but it does not solve the problem
Although I'm skeptical as to the code above doing anything at all as posted, if even compiling, here's the solution I use for doing automatic update downloads of large (>100 MB) files:
HttpGet httpGet;
RequestConfig requestConfig;
getProxySettings();
//Check to see if there is a proxy availabble.
if (!LicensePreloader.proxyAddr.equals("")) {
requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setProxy(new HttpHost(LicensePreloader.proxyAddr, LicensePreloader.proxyPort))
.build();
} else {
//No proxy was available, just use regular internet.
requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
}
httpGet = new HttpGet(this.remoteUrl);
HttpResponse response;
InputStream remoteContentStream = null;
OutputStream localFileStream = null;
try {
httpGet.setConfig(requestConfig);
response = httpClient.execute(httpGet);
//This builds the content of our file we're downloading.
remoteContentStream = response.getEntity().getContent();
long fileSize = response.getEntity().getContentLength();
File dir = localFile.getParentFile();
dir.mkdirs();
localFileStream = new FileOutputStream(localFile);
//Set the buffer, in our use case, it's always the deafult 8192 bytes.
byte[] buffer = new byte[bufferSize];
int sizeOfChunk;
int amountComplete = 0;
//Simply loop through and download the file in 'chunks'
while ((sizeOfChunk = remoteContentStream.read(buffer)) != -1) {
localFileStream.write(buffer, 0, sizeOfChunk);
amountComplete += sizeOfChunk;
updateProgress(amountComplete, fileSize);
}
return localFile;
} finally {
//Make sure to clean everything up.
try {
if (remoteContentStream != null) {
remoteContentStream.close();
}
if (localFileStream != null) {
localFileStream.close();
}
} catch (IOException ex) {
//If we're here, it's likely because the internet conneciton
//couldn't be established, or it was cut short in the middle.
ex.printStackTrace(System.out);
failed();
}
}
}
This is obviously overkill for your application, and you can probably just forget all the proxy business, but I kept it in there for completeness sake. There are a couple helper methods I didn't include, but again, they're almost all exclusively for proxy handling.
good luck!
You are writing one the first read in the input. You need to write the file until the input is empty.
Try this while in you code
while ((count = in.read(data)) != -1) {
fout.write(data, 0, count);
...
}
I have java code for file download through ftp, after download the file, it goes to default path. The specified destination path is not having the downloaded file. Why? my code is,
public class ftpUpload1
{
public static void main(String a[]) throws IOException
{
ftpUpload1 obj = new ftpUpload1();
URL url1 = new URL("ftp://vbalamurugan:vbalamurugan#192.168.6.38/ddd.txt" );
File dest = new File("D:/rvenkatesan/Software/ddd.txt");
obj.ftpDownload(dest, url1);
public void ftpDownload(File destination,URL url) throws IOException
{
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try
{
URLConnection urlc = url.openConnection();
bis = new BufferedInputStream( urlc.getInputStream() );
bos = new BufferedOutputStream( new
FileOutputStream(destination.getName() ) );
int i;
//read byte by byte until end of stream
while ((i = bis.read())!= -1)
{
// bos.write(i);
bos.write(i);
}
System.out.println("File Downloaded Successfully");
}
finally
{
if (bis != null)
try
{
bis.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
if (bos != null)
try
{
bos.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
}
}
The downloaded file "ddd.txt" not in the "D:/rvenktesan/Software". It is located in "D:rvenkatesan/JAVA PROJECTS". Why? guide me to store the file in specified path? Thanks in adcance.
You problem is FileOutputStream(destination.getName() ) );
change this to: FileOutputStream(destination.getAbsolutePath() ) );
getName wil return the filename "ddd.txt" only. I assume you are starting your app from D:/rvenkatesan/JAVA PROJECTS