Android: get real filepath from uri without copying to filestream - java

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.

Related

Java : download file outside server context

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

Javax : Try to find a solution to open an AVI within jar

I tried to open an AVI within the executable jar file, the only solution I found is to use FileOutputStream and to make a copy in a temporary file :
InputStream inputStream = getClass().getResourceAsStream(filePathInJar);
int read = 0;
byte[] bytes = new byte[1024];
this.file = new File("c:\\tmpfile.avi");
OutputStream out = new FileOutputStream(file);
while ((read = inputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
inputStream.close();
out.flush();
out.close();
And then I can make :
mediaPlayer = Manager.createRealizedPlayer(new File("c:\\tmpfile.avi").toURI().toURL());
First question : Do you have any better solution?
So with this solution I would delete the temporary file at the end of his use and I tried :
mediaPlayer.stop();
mediaPlayer.close();
mediaPlayer.deallocate();
file.delete()
But deletion doesn't work. It seems to be always in use in the player...
Second question : How can I stop the use of the temporary file or force to delete?
Thanks.
I haven't tried this, but you could try using getClass().getResource(filePathInJar) to get a URL for the resource, and then use that to construct a MediaLocator to use as the parameter to createRealizedPlayer(). Something like:
URL url = getClass().getResource(filePathInJar);
MediaLocator locator = new MediaLocator(url);
mediaPlayer = Manager.createRealizedPlayer(locator);
Edit:
So, I've verified that MediaLocator cannot deal with a jar:file:/ url.
It seems to me that you have two choices:
Find or create a custom InputStream-based DataSource. The page at http://www.extollit.com/isdsjmf.php claims to have one that works. I haven't tried it.
Keep doing what you're doing now - copy the media file from the jar to a temp file, and use a file:// url.
I think that you can solve your problem with deleting the file by using File.createTempFile() and File.deleteOnExit()

Why pdf files downloads as corrupted?

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.

Java + Google Web Toolkit (google apps engine) download file from server

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.

Create a file object from a resource path to an image in a jar file

I need to create a File object out of a file path to an image that is contained in a jar file after creating a jar file. If tried using:
URL url = getClass().getResource("/resources/images/image.jpg");
File imageFile = new File(url.toURI());
but it doesn't work. Does anyone know of another way to do it?
To create a file on Android from a resource or raw file I do this:
try{
InputStream inputStream = getResources().openRawResource(R.raw.some_file);
File tempFile = File.createTempFile("pre", "suf");
copyFile(inputStream, new FileOutputStream(tempFile));
// Now some_file is tempFile .. do what you like
} catch (IOException e) {
throw new RuntimeException("Can't create temp file ", e);
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
Don't forget to close your streams etc
This should work.
String imgName = "/resources/images/image.jpg";
InputStream in = getClass().getResourceAsStream(imgName);
ImageIcon img = new ImageIcon(ImageIO.read(in));
Usually, you can't directly get a java.io.File object, since there is no physical file for an entry within a compressed archive. Either you live with a stream (which is best most in the cases, since every good API can work with streams) or you can create a temporary file:
URL imageResource = getClass().getResource("image.gif");
File imageFile = File.createTempFile(
FilenameUtils.getBaseName(imageResource.getFile()),
FilenameUtils.getExtension(imageResource.getFile()));
IOUtils.copy(imageResource.openStream(),
FileUtils.openOutputStream(imageFile));
You cannot create a File object to a reference inside an archive. If you absolutely need a File object, you will need to extract the file to a temporary location first. On the other hand, most good API's will also take an input stream instead, which you can get for a file in an archive.

Categories