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();
}
}
Related
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;
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();
}
I am using serveResource to allow download files of document library through my portlet.
However, it only shows the downloaded size but not the size to be downloaded.
String mimetype = doc_file.getMimeType(); //doc_file is fileentry from document library
if (mimetype == null) {
mimetype = "application/octet-stream";
}
res.setContentType(mimetype); // res is ResourceResponse
res.addProperty(HttpHeaders.CONTENT_DISPOSITION,
" filename=\"" +
DocumentUtil.docNamingConvention(doc_file.getTitle(), "get") +
"." + doc_file.getExtension() + "\"" );
long zipFileLength = doc_file.getSize();
res.addProperty(HttpHeaders.CONTENT_LENGTH, Long.toString(zipFileLength));
FileInputStream input = (FileInputStream) doc_file.getContentStream();
OutputStream out = res.getPortletOutputStream();
byte[] buf = new byte[4096];
int bytesread = 0, bytesBuffered = 0;
System.out.println(input.toString().length());
while((bytesread = input.read(buf)) > -1) {
out.write(buf, 0, bytesread);
bytesBuffered += bytesread;
if (bytesBuffered > 1024 * 1024) { //flush after 1MB
bytesBuffered = 0;
out.flush();
}
}
input.close();
out.close();
This code is working in Mozilla, Mozilla is showing total file size and size of data downloaded , but not in Internet Explorer and Chrome.
I made a code that sending files from one computer to another,
the problem is that after one sending its not working anymore.
I know that the problem is when i'm writing to the writer but I don't know why its not working.
client:
File file =new File(path);
long fileSize = file.length();
long completed = 0;
int step = 150000;
Request req = new Request(RequetType.DOWNLOAD_FILE,file.getName());
writer.writeObject(req);
writer.flush();
// creates the file stream
FileInputStream fileStream = new FileInputStream(file);
// sending a message before streaming the file
// writer.writeObject("SENDING_FILE|" + file.getName() +"|" + fileSize);
writer.reset();
byte[] buffer = new byte[step];
while (completed <= fileSize) {
fileStream.read(buffer);
writer.write(buffer);
completed += step;
}
System.out.println(completed);
//writer.writeObject("SEND_COMPLETE");
fileStream.close();
server:
String filename = (String)req.getContent();
try {
FileOutputStream outStream =new FileOutputStream(Startdir+""+filename);
byte[] buffer = new byte[200000];
int bytesRead = 0, counter = 0;
bytesRead = this.reader.read(buffer);
if (bytesRead >= 0) {
outStream.write(buffer, 0, bytesRead);
counter += bytesRead;
System.out.println("total bytes read: " +
counter);
}
if (bytesRead < 1024) {
outStream.flush();
}
while (true)
{
bytesRead = this.reader.read(buffer);
if (bytesRead >= 0) {
outStream.write(buffer, 0, bytesRead);
counter += bytesRead;
System.out.println("total bytes read: " +
counter);
}
if (bytesRead ==0)
{
outStream.flush();
break;
}
}
System.out.println("Sent:"+filename+" from:"+MainApp.computersconnection.getIp());
} catch (Exception e) {
System.out.println("Error on downloading file!");
}
You need to flush the streams in the end even if the file isn't 0 bytes long. Try implementing that change and tell me if it still gives you trouble.
(Flush the output stream when your done sending a file).
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);
}