Servlet - Force overwrite downloaded file - java

How to change this code to force overwrite existing previously opened file saved on drive? It's part of servlet for opening pdf files on client side.
response.reset();
response.setContentType("application/pdf");
response.setContentLength(file.length());
response.setHeader("Content-disposition", "inline; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try
{
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0)
{
output.write(buffer, 0, length);
}
}
finally
{
close(output);
close(input);
}
Each next copy of opened file has a new index, e.g. test.pdf, test(1).pdf and so on

You can't control that.
That is dependent on client's OS file system implementation

The best you can do it to configure the client browser to ask whether to overwrite or not, for example in Firefox it is:
To my knowledge asking to overwrite is the default behavior in Opera.

before going to write check whether the given file is exist or not?
using file api file.exists() if it exists, delete given file using file api file.delete() and continue with writing process

Related

java - HttpServlet file download

I tried to create a file, write to it and then turn the file into an input stream and transfer its bytes to the output stream of the HTTP response. But I get the message "/tmp/mozilla_xxxx/33JJ1OHw.md.part could not be saved, because the source file could not be read." when testing it.
Here's the code that does this part.
f = new File("f.md");
f.createNewFile();
fw = new FileWriter(f);
fw.append("#" + query + "\n" + queryResult);
fw.close();
resp.setContentType("text/markdown");
OutputStream out = resp.getOutputStream();
FileInputStream in = new FileInputStream(f);
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.flush();
As you can see in the documentation, File class is not meant to read the actual file content, it is just...
An abstract representation of file and directory pathnames.
But, there are many ways of getting file's content, just use one of the following classes: FileReader, BufferedReader, Scanner and Files.
Here you'll see different examples to do that, just use the one you find better. Different ways of Reading a text file in Java

java - downloading a input stream using servlets

I am using the following code to get the content from an object in s3 bucket. I am able to copy the data into a file locally, but the file needs to be 'downloaded' and it has to be shown in the browser's downloads list.
I searched a bit about this and cam to know this has something to do with response.setHeader( "Content-Disposition", "attachment;filename=\"" + filename + "\"" );
I tried to add that too but somehow couldn't get it to work. My understanding is that the source has to be a file on a server which is converted into a stream. but I get the s3 contents in the form of a input stream. How to i download this as a file in the browser?
Below is the code i have tried so far
AmazonS3 s3 = new AmazonS3Client(new ProfileCredentialsProvider());
S3Object fetchFile = s3.getObject(new GetObjectRequest(bucketname, fileloc));
final BufferedInputStream i = new BufferedInputStream(fetchFile.getObjectContent());
response.setContentType("application/json");
response.setHeader( "Content-Disposition", "attachment;filename=\"" + filename + "\"" );
ServletOutputStream sos = response.getOutputStream();
int bytesread = i.read();
while(bytesread!=-1)
{
sos.write(bytesread);
bytesread = i.read();
}
if(i!= null)i.close();
if(sos!= null)sos.close();
Everything is correct except the file reading part.
//Set the size of buffer to stream the data.
byte []buffer=new byte[1024*8];
instead of
int byte=i.read();
Now read the file.
while( ( length = yourInputStream.read(buffer))!=-1)
{ yourOutputStream.write(buffer);
}
System.out.println("File is downloaded.");
Additionally,puting your whole code within try/catch block will help you to know the exact reason of your problem.

Download servlet is very slow

I have written a servlet which will download the file from a server location. In our own INTRAnet the download seems to be very very slow and also when I have the Adobe addon installed in my browser and if I am downloading a PDF file, the Adobe addon will display the progress bar while downloading the PDF but this is not happening in my case! Below is my code! Should I not response it as attachment?
PrintWriter out = response.getWriter();
response.setContentType("APPLICATION/OCTET-STREAM");
response.setIntHeader("Refresh", 1);
response.setHeader("Content-Disposition",
"inline; filename=\"" + fileNameWithExtension
+ "\"");
FileInputStream fileInStream = new FileInputStream(
filePathWithExtension);
BufferedInputStream bufferInStream = new BufferedInputStream(
fileInStream);
int cnt;
while ((cnt = bufferInStream.read()) != -1) {
out.write(cnt);
}
fileInStream.close();
out.close();
Not sure if there is a better way to do. Basically I tried converting one of my dot net code into this Java Servlet. THe current .NET code is very fast compared to this!
This is hosted on Apache Tomcat and the .NET code is hosted on IIS.
Reading and writing a byte at a time is horrifically inefficient. The canonical way to copy a stream in Java is as follows:
byte[] buffer = new byte[8192]; // or more if you like
int count;
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
And you should not use a Writer here, use an OutputStream.

Java: Binary File Upload using Restlet + Apache Commons FileUpload

I have a REST API with Restlet 2.3 and need to implement a file-uploading functionality to it.
The problem is that, when someone uploads a file using a POST (with a multipart/form-data Content-Type), the file reaches the server with another encoding.
To test this, I printed the contents of the original file in a Unix Terminal and then printed it again before parsing the requet with Apache Commons FileUpload (with almost the same code of this example http://restlet.com/technical-resources/restlet-framework/guide/2.2/extensions/fileupload). Both printed contents are very similar, but the original file has less characters, so i assume that my Java server is using the wrong encoding to interpret the file.
The file I sent is a PNG image. With text files the server works perfectly, but when I send photos or any binary file, the problem appears.
I don't know how you exactly did to check the received content. First you should check the content type that is used for your file part within the content of your multipart request. You should have something like that for a JPG image:
-----------------------------75956101888331271337088331
Content-Disposition: form-data; name="fileToUpload"; filename="myimage.jpg"
Content-Type: image/jpeg
Secondly, I don't know how you actually write the content you received. Apache Commons IO brings an utility method IOUtils.copy that provides a simple solution to write in an OutputStream the content received from an InputStream. See how ti can be used in your context:
while (fileIterator.hasNext()) {
FileItemStream fi = fileIterator.next();
if (fi.getFieldName().equals("fileToUpload")) {
FileOutputStream fos = new FileOutputStream(
"output"+File.separator+fi.getFieldName());
IOUtils.copy(fi.openStream(), fos);
fos.close();
}
}
IMO, the encoding aspect only applies for text not for binary content.
Hope it helps,
Thierry
I actually solved it by using Google's ByteStreams class:
while (fileIterator.hasNext()) {
FileItemStream fi = fileIterator.next();
if (fi.getFieldName().equals(FILE_TO_UPLOAD)) {
byte[] byteArray = ByteStreams.toByteArray(fi.openStream());
result = new String(byteArray,Charset.forName("ISO-8859-1"));
}
}
I had the similar problem when uploading the image file. This is how I fixed. The problem was in my case the data read from the inputstream. As it is reading from a socket no guarantee that you will have the full buffer of your array filled. Therefore you should check your data size before writing it to the outputbuffer/file. Here is my code hope it helps. Also available in repository https://github.com/esabilbulbul/java-servlet-fileupload/blob/master/README.md
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
upload.setHeaderEncoding("UTF-8");
// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext())
{
FileItemStream item = iter.next();
String name = item.getFieldName();
//InputStream attachmentStream = item.openStream();
//byte[] attachmentBytes = ByteStreams.toByteArray(attachmentStream);
//InputStream stream = item.getInputStream();
InputStream stream = item.openStream();
if (item.isFormField())
{
//System.out.println("Form field " + name + " with value " + Streams.asString(stream) + " detected.");
}
else
{
System.out.println("File field " + name + " with file name "+ item.getName() + " detected.");
// Process the input stream
FileOutputStream fout= new FileOutputStream ("c:\\" + item.getName());
BufferedOutputStream bout= new BufferedOutputStream (fout);
BufferedInputStream bin= new BufferedInputStream(stream);
byte buf[] = new byte[2048];
int len=0;
while ((len = bin.read(buf)) > 0)//((bin.read(buf)) != -1)
{
bout.write(buf, 0, len);
if (len<2048)
len = len;
}
bout.close();
bin.close();
}
}

Access local directory image from web app running in jetty

My web application is written using jsp/javascripts. Backend Java. Have managed to implement the code to save an image outside webapplication, because I dont want to save the images in webapp/images folder(because when the server is down and when rebuild the app, I lose those saved images). What I want is to access those images I saved in my local directory again from my web app but I dont know how to. How can I access my local folder from jetty server, and jetty server is running on the same local machine...
Get the path to /image to store & read files by
getServletContext().getRealPath("/images");
Even you can read the file from external location from your servlet
File image = new File("d:\\image\1.jpg");
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(image.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
// Open streams.
input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
// Gently close streams.
close(output);
close(input);
}
Also See
Image Servlet

Categories

Resources