Android/Java - How to retrieve image from web service and show it - java

I'm using some services of a web service which usually returns JSON respones, but one service when I send the ID of a user returns a static GIF image (Not animated).
The procedure that I'm doing is:
1.Connect to web service using DefaultHttpClient
2.Convert the InputStream received to a String with this utilitary method:
public static String inputStreamToStringScanner(InputStream in) {
Scanner fileScanner = new Scanner(in);
StringBuilder inputStreamString = new StringBuilder();
while(fileScanner.hasNextLine())
inputStreamString.append(fileScanner.nextLine()).append("\n");
fileScanner.close();
return inputStreamString.toString();
}
3.Storage the converted received String to process the server response.
For the Image Service, when I see the string converted, it begins like this:
"GIF89a?��?�� ..."
It's a static GIF file.
I'm not being able to show the image in a ImageView, I have tried different things that I found in the web:
public void onPhotoFinished (String responseData) {
InputStream is = new ByteArrayInputStream(responseData.getBytes());
Bitmap bm = BitmapFactory.decodeStream(is);
userImage.setImageBitmap(bm);
}
This is something else that I have also tried:
public void onPhotoFinished (String responseData) {
InputStream is = new ByteArrayInputStream(responseData.getBytes());
final Bitmap bm = BitmapFactory.decodeStream(new BufferedInputStream(is));
userImage.setImageBitmap(bm);
}
This also doesn't works:
public void onPhotoFinished (String responseData) {
InputStream is = new ByteArrayInputStream(responseData.getBytes());
Drawable d = Drawable.createFromStream(is, "src name");
userImage.setImageDrawable(d);
}
Finally, this doesn't work either:
public void onPhotoFinished (String responseData) {
Bitmap bm = BitmapFactory.decodeByteArray(responseData.getBytes(), 0, responseData.getBytes().length);
userImage.setImageBitmap(bm);
}
In Logcat I receive "decoder->decode returned false"
Nothing seems to work... any ideas of what is wrong?
Thanks!

Finally, I resolved it with FlushedInputStream and using directly the Input Stream, avoiding the conversion to String:
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
#Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int byteReaded = read();
if (byteReaded < 0) {
break;
} else {
bytesSkipped = 1;
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
AND:
Bitmap bitmapResponseData = BitmapFactory.decodeStream(new FlushedInputStream(is));
Regards

Related

Hibernate join multiple BLOBs

I have multiple BLOBs that I want to concat to one another, in order to get one joined BLOB. In the process, the contents of the BLOBs may not be stored in memory.
My first idea was to merge the streams like that:
long size = blobs.get(0).length();
InputStream res = blobs.get(0).getBinaryStream();
for (int i = 1; i < blobs.size(); i++){
res = Stream.concat(res, blobs.get(i).getBinaryStream());
size += blobs.get(i).length();
}
Blob blob = Hibernate.getLobCreator(session).createBlob(res, size);
However, this obviously only works with Java 8 streams (not normal BinaryStreams) - and we use Java 7 anways.
My second idea then was to join the BLOBs by directly writing into its stream:
public Blob joinBlobsForHibernate(final Session session, final List<Blob> blobs) throws SQLException {
final LobCreator lc = Hibernate.getLobCreator(session);
final Blob resBlob = lc.createBlob(new byte[0]);
try {
OutputStream stream = resBlob.setBinaryStream(1);
for (final Blob blob : blobs) {
pipeInputStream(blob.getBinaryStream(), stream);
}
return resBlob;
} catch (IOException | SQLException e){
logger.error("Creating the blob threw an exception", e);
return null;
}
}
(pipeInputStream merely pipes the content of one stream into the other:
private void pipeInputStream (final InputStream is, final OutputStream os) throws IOException {
final int buffSize = 128000;
int n;
final byte[] buff = new byte[buffSize];
while ((n = is.read(buff)) >= 0){
os.write(buff, 0, n);
}
)
This however yields in the following exception:
java.lang.UnsupportedOperationException: Blob may not be manipulated from creating session
And besides, I have the suspicion that the BLOB would still temporarily store the whole content in memory.
As a third try I tried using a custom InputStream:
/**
* Combines multiple streams into one
*/
public class JoinedInputStream extends InputStream {
private List<InputStream> parts;
private List<InputStream> marked;
public JoinedInputStream(final List<InputStream> parts) {
this.parts = parts;
}
#Override
public int read() throws IOException {
int res = -1;
while (res == -1 && parts.size() > 0) {
try {
if ((res = parts.get(0).read()) == -1) {
// The stream is done, so we won't try to read from it again
parts.remove(0);
}
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
return res;
}
#Override
public synchronized void reset() throws IOException {
parts = new ArrayList<>(marked);
if (parts.size() > 0) {
parts.get(0).reset();
}
}
#Override
public synchronized void mark(final int readlimit) {
marked = new ArrayList<>(parts);
if (marked.size() > 0)
marked.get(0).mark(readlimit);
}
#Override
public boolean markSupported() {
return true;
}
#Override
public void close() throws IOException {
super.close();
for (final InputStream part : parts) {
part.close();
}
parts = new ArrayList<>();
marked = new ArrayList<>();
}
}
The BLOB could then be joined like that (don't mind the unnecessary functions, they have other uses):
#Override
public Blob createBlobForHibernate(final Session session, final InputStream stream, final long length) {
final LobCreator lc = Hibernate.getLobCreator(session);
return lc.createBlob(stream, length);
}
#Override
public Blob createBlobForHibernate(final Session session, final List<InputStream> streams, final long length) {
final InputStream joined = new JoinedInputStream(streams);
return createBlobForHibernate(session, joined, length);
}
#Override
public Blob joinBlobsForHibernate(final Session session, final List<Blob> blobs) throws SQLException {
long length = 0;
List<InputStream> streams = new ArrayList<>(blobs.size());
for (final Blob blob : blobs) {
length += blob.length();
streams.add(blob.getBinaryStream());
}
return createBlobForHibernate(session, streams, length);
}
However, this results in the following error (when persisting the newly created entity with the joined BLOB):
Caused by: java.sql.SQLException: LOB-Lese-/Schreibfunktionen aufgerufen, während ein anderer Lese-/Schreibvorgang ausgeführt wird: getBytes()
at oracle.jdbc.driver.T4CConnection.getBytes(T4CConnection.java:3200)
at oracle.sql.BLOB.getBytes(BLOB.java:391)
at oracle.jdbc.driver.OracleBlobInputStream.needBytes(OracleBlobInputStream.java:166)
... 101 more
Or in English:
Lob read/write functions called while another read/write is in progress: getBytes()
I already tried setting hibernate.temp.use_jdbc_metadata_defaults to false (as suggested in this post) - in fact, we already had this property set beforehand and it didn't help.

Request Body Shorter than Sent by Client - HttpServer Java

I create Java Application using HttpServer as bellow:
public class Application
{
public static void main(String args[])
{
HttpServer httpPaymentServer;
httpPaymentServer = HttpServer.create(new InetSocketAddress(Config.portPayment), 0);
httpPaymentServer.createContext("/json", new Payment("json"));
}
public class Payment implements HttpHandler
{
public Payment(String dataType)
{
}
public void handle(HttpExchange httpExchange) throws IOException
{
String body = "";
if(httpExchange.getRequestMethod().equalsIgnoreCase("POST"))
{
try
{
Headers requestHeaders = httpExchange.getRequestHeaders();
Set<Map.Entry<String, List<String>>> entries = requestHeaders.entrySet();
int contentLength = Integer.parseInt(requestHeaders.getFirst("Content-length"));
InputStream inputStream = httpExchange.getRequestBody();
byte[] postData = new byte[contentLength];
int length = inputStream.read(postData, 0, contentLength);
if(length < contentLength)
{
}
else
{
String fullBody = new String(postData);
Map<String, String> query = Utility.splitQuery(fullBody);
body = query.getOrDefault("data", "").toString();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
On my server (Centos 7), on the first request, it is no problem. But on next request, not all of the request body can be read.
But on my PC (Windows 10) no problem.
What is the problem.
For your InputStream you call read only once - it may not return all the data. That data may even be not received at that time.
Instead you should call read in a loop until you get all the bytes (when you reach end of stream read returns -1). Or use one of the approaches suggested here How to read / convert an InputStream into a String in Java?
Thank you. This work for me
public void handle(HttpExchange httpExchange) throws IOException
{
String body = "";
if(httpExchange.getRequestMethod().equalsIgnoreCase("POST"))
{
try
{
Headers requestHeaders = httpExchange.getRequestHeaders();
Set<Map.Entry<String, List<String>>> entries = requestHeaders.entrySet();
int contentLength = Integer.parseInt(requestHeaders.getFirst("Content-length"));
InputStream inputStream = httpExchange.getRequestBody();
int j;
String fullBody = "";
for(j = 0; j < contentLength; j++)
{
byte b = (byte) httpExchange.getRequestBody().read();
fullBody += String.format("%c", b);
}
Map<String, String> query = Utility.splitQuery(fullBody);
body = query.getOrDefault("data", "").toString();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

Why isn't this multithreaded code faster?

This is my java code. Before, it calls BatchGenerateResult sequentially which is a lengthy process, but I want to try some multithreading and have each one of them run at the same time. However when I test it, the new time is the same as the old time. I expected the new time to be faster. Does anyone know whats wrong?
public class PlutoMake {
public static String classDir;
public static void main(String[] args) throws JSONException, IOException,
InterruptedException {
// determine path to the class file, I will use it as current directory
String classDirFile = PlutoMake.class.getResource("PlutoMake.class")
.getPath();
classDir = classDirFile.substring(0, classDirFile.lastIndexOf("/") + 1);
// get the input arguments
final String logoPath;
final String filename;
if (args.length < 2) {
logoPath = classDir + "tests/android.png";
filename = "result.png";
} else {
logoPath = args[0];
filename = args[1];
}
// make sure the logo image exists
File logofile = new File(logoPath);
if (!logofile.exists() || logofile.isDirectory()) {
System.exit(1);
}
// get the master.js file
String text = readFile(classDir + "master.js");
JSONArray files = new JSONArray(text);
ExecutorService es = Executors.newCachedThreadPool();
// loop through all active templates
int len = files.length();
for (int i = 0; i < len; i += 1) {
final JSONObject template = files.getJSONObject(i);
if (template.getBoolean("active")) {
es.execute(new Runnable() {
#Override
public void run() {
try {
BatchGenerateResult(logoPath, template.getString("template"),
template.getString("mapping"),
template.getString("metadata"), template.getString("result")
+ filename, template.getString("filter"),
template.getString("mask"), template.getInt("x"),
template.getInt("y"), template.getInt("w"),
template.getInt("h"));
} catch (IOException | JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
es.shutdown();
boolean finshed = es.awaitTermination(2, TimeUnit.MINUTES);
}
private static void BatchGenerateResult(String logoPath, String templatePath,
String mappingPath, String metadataPath, String resultPath,
String filter, String maskPath, int x, int y, int w, int h)
throws IOException, JSONException {
ColorFilter filterobj = null;
if (filter.equals("none")) {
filterobj = new NoFilter();
} else if (filter.equals("darken")) {
filterobj = new Darken();
} else if (filter.equals("vividlight")) {
filterobj = new VividLight();
} else {
System.exit(1);
}
String text = readFile(classDir + metadataPath);
JSONObject metadata = new JSONObject(text);
Map<Point, Point> mapping = MyJSON.ReadMapping(classDir + mappingPath);
BufferedImage warpedimage = Exporter.GenerateWarpedLogo(logoPath, maskPath,
mapping, metadata.getInt("width"), metadata.getInt("height"));
// ImageIO.write(warpedimage, "png", new FileOutputStream(classDir +
// "warpedlogo.png"));
Exporter.StampLogo(templatePath, resultPath, x, y, w, h, warpedimage,
filterobj);
warpedimage.flush();
}
private static String readFile(String path) throws IOException {
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[(int) file.length()];
fis.read(data);
fis.close();
String text = new String(data, "UTF-8");
return text;
}
}
It looks like, for all practical purposes the following code should be the only one which can improve performance by using multithreading.
BufferedImage warpedimage = Exporter.GenerateWarpedLogo(logoPath, maskPath,
mapping, metadata.getInt("width"), metadata.getInt("height"));
// ImageIO.write(warpedimage, "png", new FileOutputStream(classDir +
// "warpedlogo.png"));
Exporter.StampLogo(templatePath, resultPath, x, y, w, h, warpedimage,
filterobj);
The rest of it major IO - I doubt how much performance improvement you can achieve there.
Do a profile and check how long each one of the methods is executing. Depending on that you should be able to understand.
Hi sorry not able add to comment part as just joined..
would suggest to first go for dummy method any check whether it works at your end then add your business logic...
if the sample works then you might need to check your "template" class
here's the sample.. check the timestamp
package example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorStaticExample {
public static void main(String[] args){
ExecutorService ex = Executors.newCachedThreadPool();
for (int i=0;i<10;i++){
ex.execute(new Runnable(){
#Override
public void run() {
helloStatic();
System.out.println(System.currentTimeMillis());
}
});
}
}
static void helloStatic(){
System.out.println("hello form static");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

using dbpedia spotlight in java or scala

Does anyone know where to find a little how to on using dbpedia spotlight in java or scala? Or could anyone explain how it's done? I can't find any information on this...
The DBpedia Spotlight wiki pages would be a good place to start.
And I believe the installation page has listed the most popular ways (using a jar, or set up a web service) to use the application.
It includes instructions on using the Java/Scala API with your own installation, or calling the Web Service.
There are some additional data needed to be downloaded to run your own server for full service, good time to make a coffee for yourself.
you need download dbpedia spotlight (jar file) after that u can use next two classes ( author pablomendes ) i only make some change .
public class db extends AnnotationClient {
//private final static String API_URL = "http://jodaiber.dyndns.org:2222/";
private static String API_URL = "http://spotlight.dbpedia.org:80/";
private static double CONFIDENCE = 0.0;
private static int SUPPORT = 0;
private static String powered_by ="non";
private static String spotter ="CoOccurrenceBasedSelector";//"LingPipeSpotter"=Annotate all spots
//AtLeastOneNounSelector"=No verbs and adjs.
//"CoOccurrenceBasedSelector" =No 'common words'
//"NESpotter"=Only Per.,Org.,Loc.
private static String disambiguator ="Default";//Default ;Occurrences=Occurrence-centric;Document=Document-centric
private static String showScores ="yes";
#SuppressWarnings("static-access")
public void configiration(double CONFIDENCE,int SUPPORT,
String powered_by,String spotter,String disambiguator,String showScores){
this.CONFIDENCE=CONFIDENCE;
this.SUPPORT=SUPPORT;
this.powered_by=powered_by;
this.spotter=spotter;
this.disambiguator=disambiguator;
this.showScores=showScores;
}
public List<DBpediaResource> extract(Text text) throws AnnotationException {
LOG.info("Querying API.");
String spotlightResponse;
try {
String Query=API_URL + "rest/annotate/?" +
"confidence=" + CONFIDENCE
+ "&support=" + SUPPORT
+ "&spotter=" + spotter
+ "&disambiguator=" + disambiguator
+ "&showScores=" + showScores
+ "&powered_by=" + powered_by
+ "&text=" + URLEncoder.encode(text.text(), "utf-8");
LOG.info(Query);
GetMethod getMethod = new GetMethod(Query);
getMethod.addRequestHeader(new Header("Accept", "application/json"));
spotlightResponse = request(getMethod);
} catch (UnsupportedEncodingException e) {
throw new AnnotationException("Could not encode text.", e);
}
assert spotlightResponse != null;
JSONObject resultJSON = null;
JSONArray entities = null;
try {
resultJSON = new JSONObject(spotlightResponse);
entities = resultJSON.getJSONArray("Resources");
} catch (JSONException e) {
//throw new AnnotationException("Received invalid response from DBpedia Spotlight API.");
}
LinkedList<DBpediaResource> resources = new LinkedList<DBpediaResource>();
if(entities!=null)
for(int i = 0; i < entities.length(); i++) {
try {
JSONObject entity = entities.getJSONObject(i);
resources.add(
new DBpediaResource(entity.getString("#URI"),
Integer.parseInt(entity.getString("#support"))));
} catch (JSONException e) {
LOG.error("JSON exception "+e);
}
}
return resources;
}
}
second class
/**
* #author pablomendes
*/
public abstract class AnnotationClient {
public Logger LOG = Logger.getLogger(this.getClass());
private List<String> RES = new ArrayList<String>();
// Create an instance of HttpClient.
private static HttpClient client = new HttpClient();
public List<String> getResu(){
return RES;
}
public String request(HttpMethod method) throws AnnotationException {
String response = null;
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
// Execute the method.
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
LOG.error("Method failed: " + method.getStatusLine());
}
// Read the response body.
byte[] responseBody = method.getResponseBody(); //TODO Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
response = new String(responseBody);
} catch (HttpException e) {
LOG.error("Fatal protocol violation: " + e.getMessage());
throw new AnnotationException("Protocol error executing HTTP request.",e);
} catch (IOException e) {
LOG.error("Fatal transport error: " + e.getMessage());
LOG.error(method.getQueryString());
throw new AnnotationException("Transport error executing HTTP request.",e);
} finally {
// Release the connection.
method.releaseConnection();
}
return response;
}
protected static String readFileAsString(String filePath) throws java.io.IOException{
return readFileAsString(new File(filePath));
}
protected static String readFileAsString(File file) throws IOException {
byte[] buffer = new byte[(int) file.length()];
#SuppressWarnings("resource")
BufferedInputStream f = new BufferedInputStream(new FileInputStream(file));
f.read(buffer);
return new String(buffer);
}
static abstract class LineParser {
public abstract String parse(String s) throws ParseException;
static class ManualDatasetLineParser extends LineParser {
public String parse(String s) throws ParseException {
return s.trim();
}
}
static class OccTSVLineParser extends LineParser {
public String parse(String s) throws ParseException {
String result = s;
try {
result = s.trim().split("\t")[3];
} catch (ArrayIndexOutOfBoundsException e) {
throw new ParseException(e.getMessage(), 3);
}
return result;
}
}
}
public void saveExtractedEntitiesSet(String Question, LineParser parser, int restartFrom) throws Exception {
String text = Question;
int i=0;
//int correct =0 ; int error = 0;int sum = 0;
for (String snippet: text.split("\n")) {
String s = parser.parse(snippet);
if (s!= null && !s.equals("")) {
i++;
if (i<restartFrom) continue;
List<DBpediaResource> entities = new ArrayList<DBpediaResource>();
try {
entities = extract(new Text(snippet.replaceAll("\\s+"," ")));
System.out.println(entities.get(0).getFullUri());
} catch (AnnotationException e) {
// error++;
LOG.error(e);
e.printStackTrace();
}
for (DBpediaResource e: entities) {
RES.add(e.uri());
}
}
}
}
public abstract List<DBpediaResource> extract(Text text) throws AnnotationException;
public void evaluate(String Question) throws Exception {
evaluateManual(Question,0);
}
public void evaluateManual(String Question, int restartFrom) throws Exception {
saveExtractedEntitiesSet(Question,new LineParser.ManualDatasetLineParser(), restartFrom);
}
}
main()
public static void main(String[] args) throws Exception {
String Question ="Is the Amazon river longer than the Nile River?";
db c = new db ();
c.configiration(0.0, 0, "non", "CoOccurrenceBasedSelector", "Default", "yes");
System.out.println("resource : "+c.getResu());
}
I just add one little fix for your answer.
Your code is running, if you add the evaluate method call:
public static void main(String[] args) throws Exception {
String question = "Is the Amazon river longer than the Nile River?";
db c = new db ();
c.configiration(0.0, 0, "non", "CoOccurrenceBasedSelector", "Default", "yes");
c.evaluate(question);
System.out.println("resource : "+c.getResu());
}
Lamine
In the request method of the second class (AnnotationClient) in Adel's answer, the author Pablo Mendes hasn't finished
TODO Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.
which is an annoying warning that needs to be removed by replacing
byte[] responseBody = method.getResponseBody(); //TODO Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
response = new String(responseBody);
with
Reader in = new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8");
StringWriter writer = new StringWriter();
org.apache.commons.io.IOUtils.copy(in, writer);
response = writer.toString();

Download file using java apache commons?

How can I use the library to download a file and print out bytes saved? I tried using
import static org.apache.commons.io.FileUtils.copyURLToFile;
public static void Download() {
URL dl = null;
File fl = null;
try {
fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
copyURLToFile(dl, fl);
} catch (Exception e) {
System.out.println(e);
}
}
but I cannot display bytes or a progress bar. Which method should I use?
public class download {
public static void Download() {
URL dl = null;
File fl = null;
String x = null;
try {
fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
OutputStream os = new FileOutputStream(fl);
InputStream is = dl.openStream();
CountingOutputStream count = new CountingOutputStream(os);
dl.openConnection().getHeaderField("Content-Length");
IOUtils.copy(is, os);//begin transfer
os.close();//close streams
is.close();//^
} catch (Exception e) {
System.out.println(e);
}
}
If you are looking for a way to get the total number of bytes before downloading, you can obtain this value from the Content-Length header in http response.
If you just want the final number of bytes after the download, it is easiest to check the file size you just write to.
However if you want to display the current progress of how many bytes have been downloaded, you might want to extend apache CountingOutputStream to wrap the FileOutputStream so that everytime the write methods are called it counts the number of bytes passing through and update the progress bar.
Update
Here is a simple implementation of DownloadCountingOutputStream. I am not sure if you are familiar with using ActionListener or not but it is a useful class for implementing GUI.
public class DownloadCountingOutputStream extends CountingOutputStream {
private ActionListener listener = null;
public DownloadCountingOutputStream(OutputStream out) {
super(out);
}
public void setListener(ActionListener listener) {
this.listener = listener;
}
#Override
protected void afterWrite(int n) throws IOException {
super.afterWrite(n);
if (listener != null) {
listener.actionPerformed(new ActionEvent(this, 0, null));
}
}
}
This is the usage sample :
public class Downloader {
private static class ProgressListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// e.getSource() gives you the object of DownloadCountingOutputStream
// because you set it in the overriden method, afterWrite().
System.out.println("Downloaded bytes : " + ((DownloadCountingOutputStream) e.getSource()).getByteCount());
}
}
public static void main(String[] args) {
URL dl = null;
File fl = null;
String x = null;
OutputStream os = null;
InputStream is = null;
ProgressListener progressListener = new ProgressListener();
try {
fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/Screenshots.zip");
dl = new URL("http://ds-forums.com/kyle-tests/uploads/Screenshots.zip");
os = new FileOutputStream(fl);
is = dl.openStream();
DownloadCountingOutputStream dcount = new DownloadCountingOutputStream(os);
dcount.setListener(progressListener);
// this line give you the total length of source stream as a String.
// you may want to convert to integer and store this value to
// calculate percentage of the progression.
dl.openConnection().getHeaderField("Content-Length");
// begin transfer by writing to dcount, not os.
IOUtils.copy(is, dcount);
} catch (Exception e) {
System.out.println(e);
} finally {
IOUtils.closeQuietly(os);
IOUtils.closeQuietly(is);
}
}
}
commons-io has IOUtils.copy(inputStream, outputStream). So:
OutputStream os = new FileOutputStream(fl);
InputStream is = dl.openStream();
IOUtils.copy(is, os);
And IOUtils.toByteArray(is) can be used to get the bytes.
Getting the total number of bytes is a different story. Streams don't give you any total - they can only give you what is currently available in the stream. But since it's a stream, it can have more coming.
That's why http has its special way of specifying the total number of bytes. It is in the response header Content-Length. So you'd have to call url.openConnection() and then call getHeaderField("Content-Length") on the URLConnection object. It will return the number of bytes as string. Then use Integer.parseInt(bytesString) and you'll get your total.

Categories

Resources