How to resume downloading files and show the progress in java - java

I want to code a way to resume the download file in Java and show the progress if possible.
The following code was used to subtract the total size of the downloaded file (totalSize - downloaded) instead of completing the download.
URL url = new URL(urlFile);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
File SDCardRoot = Environment.getExternalStorageDirectory();
file = new File(SDCardRoot,"/MySchool/"+Folder+"/"+nameBook.getText().toString()+".pdf");
urlConnection.setRequestProperty("Range", "bytes=" + file.length() + "-");
urlConnection.setDoOutput(true);
urlConnection.connect();
outputStream = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file which we are downloading
totalSize = urlConnection.getContentLength();
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
outputStream.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
}
outputStream.close();

This might be useful for pause and resume but please specify exact problem.
if (outputFileCache.exists())
{
connection.setAllowUserInteraction(true);
connection.setRequestProperty("Range", "bytes=" + outputFileCache.length() + "-");
}
connection.setConnectTimeout(14000);
connection.setReadTimeout(20000);
connection.connect();
if (connection.getResponseCode() / 100 != 2)
throw new Exception("Invalid response code!");
else
{
String connectionField = connection.getHeaderField("content-range");
if (connectionField != null)
{
String[] connectionRanges = connectionField.substring("bytes=".length()).split("-");
downloadedSize = Long.valueOf(connectionRanges[0]);
}
if (connectionField == null && outputFileCache.exists())
outputFileCache.delete();
fileLength = connection.getContentLength() + downloadedSize;
input = new BufferedInputStream(connection.getInputStream());
output = new RandomAccessFile(outputFileCache, "rw");
output.seek(downloadedSize);
byte data[] = new byte[1024];
int count = 0;
int __progress = 0;
while ((count = input.read(data, 0, 1024)) != -1
&& __progress != 100)
{
downloadedSize += count;
output.write(data, 0, count);
__progress = (int) ((downloadedSize * 100) / fileLength);
}
output.close();
input.close();
}

Related

Pdf File does not display text correctly when sent over socket connection

I'm sending a pdf file from my java server to an android client. However when I look at the pdf file on the phone, the text is sometimes wrong (just some random symbols). Does someone know what is causing that problem?
Here is the code of the server:
private void sendPdfToPhone(File pdf) {
try {
InputStream iS = new FileInputStream(pdf);
DataOutputStream dOS = new DataOutputStream(new BufferedOutputStream(this.clientSocket.getOutputStream()));
String filename = pdf.getName();
byte[] bytes = new byte[(int) pdf.length()];
dOS.writeUTF(filename);
dOS.writeLong(bytes.length);
byte[] buffer = new byte[8192];
int bytesRead;
int bytesSent = 0;
while ((bytesRead = iS.read(buffer)) > 0) {
dOS.write(buffer, 0, bytesRead);
bytesSent += bytesRead;
}
dOS.close();
logger.debug("Sent file " + filename + " to Client: " + bytesSent + " / " + bytes.length);
} catch (IOException ex) {
logger.fatal(ex);
}
}
And this is the code of the Android client:
int bytesRead;
String filename = dIS.readUTF();
long fileSize = dIS.readLong();
byte[] buffer = new byte[1024];
File pdf = new File(context.getCacheDir() + "/" + filename);
if (!pdf.exists()) {
pdf.createNewFile();
FileOutputStream fOS = new FileOutputStream(pdf);
while (fileSize > 0 && (bytesRead = dIS.read(buffer, 0, (int)
Math.min(buffer.length, fileSize))) != -1) {
fOS.write(buffer, 0, bytesRead);
fileSize -= bytesRead;
}
dIS.close();
dOut.close();
}
pdfFile = pdf;
socket.close();
return pdf;

Video file streaming from java server to iPhone

I have this java servlet which serves video, this works fine in desktop and Android browsers but in iPhone video is not displayed.
here is my servlet code.
OutputStream output;
try (InputStream input = new FileInputStream(videoPath)) {
response.setContentType("video/mp4");
response.setHeader("Content-Disposition", "inline; filename=" + videoID);
output = response.getOutputStream();
byte[] buffer = new byte[2096];
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
output.close();
}
iPhone requires the server properly handle byte range requests.
Thanks, #szatmary for guidance here is the implementation please do share if there is any better impliementation.
OutputStream output;
if (request.getHeader("range") != null) {
response.setStatus(206);
String rangeValue = request.getHeader("range").trim().substring("bytes=".length());
long fileLength = outputFile.length();
long start, end;
if (rangeValue.startsWith("-")) {
end = fileLength - 1;
start = fileLength - 1 - Long.parseLong(rangeValue.substring("-".length()));
} else {
String[] range = rangeValue.split("-");
start = Long.parseLong(range[0]);
end = range.length > 1 ? Long.parseLong(range[1]) : fileLength - 1;
}
if (end > fileLength - 1) {
end = fileLength - 1;
}
if (start <= end) {
long contentLength = end - start + 1;
response.setHeader("Content-Length", contentLength + "");
response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
response.setHeader("Content-Type", "video/mp4");
response.setHeader("Content-Disposition", "inline; filename=test.mp4");
RandomAccessFile raf = new RandomAccessFile(outputFile, "r");
raf.seek(start);
output = response.getOutputStream();
byte[] buffer = new byte[2096];
int bytesRead = 0;
int totalRead = 0;
while (totalRead < contentLength) {
bytesRead = raf.read(buffer);
totalRead += bytesRead;
output.write(buffer, 0, bytesRead);
}
}
} else {
try (InputStream input = new FileInputStream(outputFile.getPath())) {
response.setContentType("video/mp4");
response.setHeader("Content-Disposition", "inline; filename=test.mp4");
response.setStatus(200);
output = response.getOutputStream();
byte[] buffer = new byte[2096];
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
output.close();
}
}

Resume file downloaded in java is corrupted

I have implemented the resume downloading after a crash or
interrupt, I successfully did that but now i am getting a corrupted
file. Can anyone please help me sorting out this problem.
URL url = new URL(f_url[0]);
HttpURLConnection conection =(HttpURLConnection) url.openConnection();
conection.setDoInput(true);
conection.setDoOutput(true);
if (downloadstatus) {
file = new File(DESTINATION_PATH + f_url[1] + EXTEN);
if (file.exists()) {
downloaded = (int) file.length();
conection.setRequestProperty("Range", "bytes=" + (file.length()) + "-");
} else {
conection.setRequestProperty("Range", "bytes=" + downloaded + "-");
}
lenghtOfFile= conection.getContentLength();
conection.connect();
input = new BufferedInputStream(conection.getInputStream());
output=(downloaded==0)? new FileOutputStream(DESTINATION_PATH + f_url[1] + EXTEN): new FileOutputStream(DESTINATION_PATH + f_url[1] + EXTEN,true);
bout = new BufferedOutputStream(output, 1024);
byte[] data = new byte[1024];
int x = 0;
long total = 0;
while ((x = input.read(data, 0, 1024)) >= 0) {
total += x;
publishProgress(""+(int)((total*100)/lenghtOfFile));
bout.write(data, 0, x);
downloaded += x;
}

No number of bytes received in java

I would like to determine the number of bytes downloaded from the following working URL connection:
I have following code to implement:
.......
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream is = connection.getInputStream(); // throws an IOException
DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
FileOutputStream fos = new FileOutputStream("C:\\Picture.jpeg");
int read =0;
byte[] bytes = new byte[1024];
while((read = dis.read(bytes)) != -1)
{
fos.write(bytes, 0, read);
}
System.out.println(read + " byte(s) copied");
The output from the last line is as follows:
Opening connection to http://www.xyz.com//Picture.jpeg...
Copying image resource (type: application/jpeg, modified on: 02/02/2010 4:19:21 AM)...
-1 byte(s) copied
What is the error of my code. please help me
int read =0;
int reddit = 0;
byte[] bytes = new byte[1024];
while((read = dis.read(bytes)) != -1)
{
fos.write(bytes, 0, read);
reddit += read;
}
//your read variable must have the value -1 at this point
System.out.println(reddit + " byte(s) copied");
int totalBytes = 0;
...
while((read = dis.read(bytes)) != -1)
{
totalBytes += read;
fos.write(bytes, 0, read);
}

file never fully downloaded

I am trying to download/resume file. Resume seems to work, but whole download brings the problem. After executing this code testfile is 5242845. But it should be 5242880! I opened this two files in the hex editor and figured out that testfile missing some bytes at the end (begining is okay). This is the code:
String url = "http://download.thinkbroadband.com/5MB.zip";
String DESTINATION_PATH = "/sdcard/testfile";
URLConnection connection;
connection = (HttpURLConnection) url.openConnection();
File file = new File(DESTINATION_PATH);
if (file.exists()) {
downloaded = (int) file.length();
connection.setRequestProperty("Range", "bytes=" + (file.length()) + "-");
}
connection.setDoInput(true);
connection.setDoOutput(true);
BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
FileOutputStream fos = (downloaded == 0) ? new FileOutputStream(DESTINATION_PATH) : new FileOutputStream(DESTINATION_PATH, true);
BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);
byte[] data = new byte[1024];
int x = 0;
int i = 0;
int lenghtOfFile = connection.getContentLength();
while ((x = in.read(data, 0, 1024)) != -1) {
i++;
bout.write(data, 0, x);
downloaded += x;
}
I think that the problem is here while ((x = in.read(data, 0, 1024)) != -1) {.
For example we have file 1030 bytes long. First write is good, bout.write(data,0,1024); but next time while ((x = in.read(data, 0, 1024)) != -1) { gets -1, because 1030-1024=6 bytes left. And we are trying to write 1024 bytes! I know it should not be so, but it seems that it is how I said. How can I figure this? Thanks.
bout.flush();
and/or
bout.close();
You need to close your BufferedOutputStream to ensure that all that is buffered is sent to the buffered OutputStream.
google told me, there is a "available" method of bufferedinputstream, so you can write like
(I´m not an java guru)
while (in.available() > 0)
{
x = in.read(data, 0, 1024);
bout.write(data, 0, x);
}

Categories