I wrote small program for downloading files via url. Every other files format I can open properly, but for downloaded pdf it's impossible.
public static void saveFile(String fileUrl, String destinationFile) throws IOException {
URL url = new URL(fileUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(destinationFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
os.flush();
is.close();
os.close();
}
Do I need special way for handling pdf downloads?
When I try to get selected pdf via URL in browser it's displays properly
EDIT
Added flush() to code, still no success
Trying to open damaged pdf in browser (FF) returns error:
File does not begin with '%PDF-'
Adobe Reader returns:
File could not be open because it is either not a supported file type
or because file has been damaged.
Damages pdf has smaller size (about 80%) than original
The damaged pdf files has website html code inside.
Related
I am creating an app that allows the user to upload multiple files to my server and I am doing the uploading with the "Fast Android Networking" Library, so I will need to provide File Objects to upload the files and can not use the Uri's I get from the filechooser.
Currently I'm getting an InputStream from a Uri and copy it into a File.
public static void copyInputStreamToFile(InputStream inputStream,
File file) throws IOException {
try (FileOutputStream outputStream = new FileOutputStream(file, false)) {
int read;
byte[] bytes = new byte[8192];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
}
}
This though, will get any device to lag pretty fast and I'd like to avoid this. I searched everywhere but couldn't find a method for converting a Uri to a File object, that works for me. If anyone knows a way to directly upload from uri, that would also work for me.
I am getting byte array from web service. this byte array is the pdf file. Below code execute well and download file on browser. But this file is seems corrupt. Also additional copy of file gets created on server which I am trying to avoid.
byte[] rawFile = myService.getDocument(param1, param2);
try (BufferedInputStream in = new BufferedInputStream(new ByteArrayInputStream(rawFile));
FileOutputStream fileOutputStream = new FileOutputStream("myfile-1.pdf")) {
byte dataBuffer[] = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
fileOutputStream.write(dataBuffer, 0, bytesRead);
}
response.setContentType("application/pdf");
response.setHeader("Content-Disposition","attachment;filename=myfile-1.pdf");
response.flushBuffer();
} catch (final Exception ex) {
ex.printStackTrace();
}
}
In a nutshell, below are 2 issue.
Downloaded file (on browser) is seems corrupt and not open. Generic pdf error message appears.
File which created on server is opening fine and shows content. But this file should not be physically present on server.
Downloaded file (on browser) is seems corrupt and not open.
Because you never sent the file content to the browser.
this file should not be physically present on server.
Then why did you explicitly write it there using FileOutputStream?
You need to write the file content to the response.
byte[] rawFile = myService.getDocument(param1, param2);
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment;filename=myfile-1.pdf");
OutputStream out = response.getOutputStream();
out.write(rawFile);
// no need to close or flush, that happens automatically when you return
I'm required for a project to send an html file through a socket in Java. I managed to get the text to appear in the browser but none of the pictures load. I found this code online to help me send the html file in the first place, but I am wondering if there is any way to send the pictures. I have all of the images in an img folder, which is where the html file is located.
public class SimpleFileServer {
public final static int SOCKET_PORT = 9000; // you may change this
public final static String FILE_TO_SEND = "D:\\Project 2\\index.html"; // you may change this
public static void main (String [] args ) throws IOException {
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(SOCKET_PORT);
while (true) {
try {
sock = servsock.accept();
// send file
File myFile = new File (FILE_TO_SEND);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = sock.getOutputStream();
os.write(mybytearray,0,mybytearray.length);
System.out.println("Done.");
} finally {
if (bis != null) bis.close();
if (os != null) os.close();
if (sock!=null) sock.close();
}
}
} finally {
if (servsock != null) servsock.close();
}
}
}
Are you sure your project does not also require you to parse the HTML and request the images separately? It sounds like you're simulating something like a web server. Generally speaking a browser will download the HTML of a page, parse it, then send follow-up requests to the server for each image or other resource (CSS, off-site Javascript, etc.) contained in the page.
Doing one request per resource can also simplify your server, because it only has to deal with the resource being requested at the time, which pushes some of the logic and complication back onto the client to be able to know which resources to ask for.
Things have changed somewhat in HTTP 2, but that's another matter that is probably outside the scope of your question.
Typically, image files are not included in the html download, but are requested subsequently as the html file is parsed. The problem of why the images are not showing in your case can probably be fixed by correcting the src locations in the tags. IF you do need to download everything together though, I would recommend sending a .zip archive
I think you are trying to achieve the "save as" functionality in web browsers.
You need to save the html file separately and the assets such as image files, embedded contents separately.
Since you already have the images in img folder, you need to alter the src attribute of image tag in the html - to pick the images from the image folder.
I need to save a file and download file in directory outside server context.
I am using Apache Tomacat
I am able to do this in directory present in webapps directory of application
If my directory structure is as follows,
--src
--WebContent
-- uploaddir
-- myfile.txt
Then I am able to download in by simply.
download
But, problem is when file is in some other directory say d:\\uploadedfile\\myfile.txt
then I wont be able to download it, as resource is not in server context as above.
I have file path to uuid mapping,
like,
d:\\uploadedfiles\\myfile.txt <-> some_uuid
then I want file should be downloaded, on click of following,
download
So, How to make file downloadable when it is outside the server context,
I heard about getResourceAsStream() method which would do this , But would any one help me on how to do this, probably with simple code snippet?
Try the below code which you can write in filedownloadservet. Fetch the file name from the request parameter and then read and write the file.
If you need to do some security checks then do that before processing the request.
File file = new File("/home/files", "file name which user wants to download");
response.setContentType(getServletContext().getMimeType(file.getName()));
response.setContentLength(file.length());
BufferedInputStream inputStream = null;
BufferedOutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(file));
outputStream = new BufferedOutputStream(response.getOutputStream());
byte[] buf = new byte[2048];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
//log it
}
}
// do the same for input stream also
}
here i found the answer,
response.setContentType("application/msword");
response.setHeader("Content-Disposition","attachment;filename=downloadname.doc");
File file=new File("d:\\test.doc");
InputStream is=new FileInputStream(file);
int read=0;
byte[] bytes = new byte[BYTES_DOWNLOAD];
OutputStream os = response.getOutputStream();
while((read = is.read(bytes))!= -1){
os.write(bytes, 0, read);
}
os.flush();
os.close();
Base path will not work that is for HTML and it works if the base path is also exposed by your web server which does not look like case here.
To download an arbitary file you need to open the file using a FileInputStream (and surround it by a buffered input stream), read a byte, then send that byte from your servlet to the client.
Then there are security concerns, so should google that (basically not give access to any file but only file that is to be shared, audit download etc as needed.
Again in your servlet set the mime type etc and then open a input stream and write the bytes to the output stream to client
I have deployed an application in Google App Engine and and I want to upload and download data from server using java code at desktop and server code for download request and one more: Where do I store the data in apps engine?
To store binary data (file contents) you have three options:
Blob property of Datastore entities
Blobstore
Google Cloud Storage
You can save your file anywhere on your server, you just need to know the path.
how i direct it as output stream?
Here is a code snippet that can help you.
File fileOnServer = new File("Hello.txt"); // Give full path where your file is located
byte[] file = new byte[(int) fileOnServer.length()];
FileInputStream fileInputStream = new FileInputStream(fileOnServer);
fileInputStream.read(file);
int contentLength = (int) file.length;
response.setContentLength(contentLength);
response.setHeader("Content-Disposition", "attachment; filename=\"Hello.txt\"");
out = response.getOutputStream();
int bytesWritten = 0;
byte[] buffer = new byte[1024];
while (bytesWritten < contentLength) {
int bytes = Math.min(1024, contentLength - bytesWritten);
System.arraycopy(file, bytesWritten, buffer, 0, bytes);
if (bytes > 0) {
out.write(buffer, 0, bytes);
bytesWritten += bytes;
} else if (bytes < 0);
}
get download to user end?
Well you can add ClickHandler on a Button on your client side and override onClick method.
public void onClick(ClickEvent event) {
Window.open("UrlToYourServelet", "_blank", "null");
}
Hope this helps!
EDIT
I have found a solution. You can upload the file at any free file hosting site like this. This site provides a URL for every uploaded file. So in your servelet, make a HTTP request to the URL and download the file in byte[] and write it on outputStream as shown in the code above.