Android - content provider file not found exception - java

I've a little content provider to open a simple pdf in my app package with an external application, but whe the open() run the parcelfiledescription return me a FileNotFoundException.
I don't understand what is the right sintax to give the correct file path to the parcel descriptor...
public ParcelFileDescriptor openFile(Uri uri, String mode) {
Log.i("info","eseguo providing");
URI uri1 = URI.create("file:///data/data/package.name/assets/prova.pdf");
File file = new File(uri1);
ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
return parcel;
}
Thanks for any help!
i've tried this simple code:
URI uri1 = URI.create("file:///android_asset/prova.pdf");
File file = new File(uri1);
Log.i("info","file exist: " + file.exists());
but it return ever false!

From [ParcelFileDescriptor.open method][1] (bold emphasis mine)
FileNotFoundException Throws FileNotFoundException if the given file does not exist or can not be opened with the requested mode.
Have you tried changing the MODE to MODE_READ_ONLY and see if that works?
[1]: http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#open(java.io.File, int)

Related

Downloading Thymeleaf template from S3

I am currently storing and downloading my Thymeleaf templates in S3.
I am using the following function to retrieve the Template from S3:
public String getTemplateFile(String name, File localFile) {
ObjectMetadata object = s3Client.getObject(new GetObjectRequest(connectionProperties.getBucket(), name), localFile);
boolean success = localFile.exists() && localFile.canRead();
return localFile.getPath();
}
After doing this the file is successfully downloaded in the desired location.
But when trying to access the file from the FlyingSaucer PDF generator the file doesn't exist, despite it is already downloaded in FILE_LOCATION_PATH. (I can open the file... the file is there but the function doesn't see it)
String xHtmlStringDocument =
convertHtmlToXhtml(templateEngine
.process(FILE_LOCATION_PATH,
initializeLetterHtmlTemplateContext(letter)));
When I run the program again and again I get the same result. But when I STOP the program and RUN it AGAIN then everything works because the file form the last execution is now recognized by the program.
This sounds to me like an asynchronous function issue.
Does anybody know how can I fix this?
Thanks in advance.
EDITED (following suggestion)
New function: Same result:
(And the file was created, the Download from S3 was successful)
java.io.FileNotFoundException: ClassLoader resource "static/templates/template.html" could not be resolved
public String getTemplateFileN(String name, File localFile) throws IOException {
S3Object fullObject = null;
InputStream in = null;
try {
fullObject = s3Client.getObject(new GetObjectRequest(connectionProperties.getBucket(), name));
System.out.println("Content-Type: " + fullObject.getObjectMetadata().getContentType());
System.out.println("Content: ");
displayTextInputStream(fullObject.getObjectContent());
in = fullObject.getObjectContent();
System.out.println(localFile.toPath());
Files.copy(in, localFile.toPath());
} //then later
finally {
// To ensure that the network connection doesn't remain open, close any open input streams.
if (fullObject != null) {
fullObject.close();
}
if (in != null) {
in.close();
}
}
return localFile.getPath();
}
Checking javadoc
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getObject-com.amazonaws.services.s3.model.GetObjectRequest-java.io.File-
I see not method signature ObjectMetadata getObject(GetObjectRequest getObjectRequest,String file)
There is
ObjectMetadata getObject(GetObjectRequest getObjectRequest,
File destinationFile)
Where you provide File (not String) as second argument. Make sure the file is not opened for write before you try reading it!

Update Google Doc with Drive API - Format lost

I'm trying to develop a Java program which retrieves a file from the Google Drive and try to reupload it "as is". However, during that process, It loses the format.
Here is how I retrive the file:
private static java.io.File downloadFile(File uploadedFile)
throws IOException {
java.io.File downloadedFile = new java.io.File(parentDir, uploadedFile.getTitle() + UUID.randomUUID().toString());
try (OutputStream out = new FileOutputStream(downloadedFile)) {
drive.files().export(uploadedFile.getId(), "text/html").executeMediaAndDownloadTo(out);
}
return downloadedFile;
}
Here is how I update the file:
private static File updateFile(Drive service, String fileId, File file, java.io.File newContent) throws IOException {
FileContent mediaContent = new FileContent("text/html", newContent);
return service.files().update(fileId, file, mediaContent).execute();
}
And here is how I combine those methods (pretty dummy):
java.io.File downloaded = downloadFile(files.get(0));
updateFile(drive, files.get(0).getId(), files.get(0), downloaded);
This is the file before and after:
The process is fine when I export & re-import the Google file as RTF or PDF, but I really need an editable format. Did I miss something?
This is the expected outcome. PDFs are one way of ensuring the formats are preserved. For Google Docs, not so much.

renaming file name inside a zip file

trying to rename internal file within a zip file without having to extract and then re-zip programatically.
example. test.zip contains test.txt, i want to change it so that test.zip will contain newtest.txt(test.txt renamed to newtest.txt, contents remain the same)
came across this link that works but unfortunately it expects test.txt to exist on the system. In the example the srcfile should exist on the server.
Blockquote Rename file in zip with zip4j
Then icame across zipnote on Linux that does the trick but unfortunately the version i have doesnt work for files >4GB.
Any suggestions on how to accomplish this? prefereably in java.
This should be possible using Java 7 Zip FileSystem provider, something like:
// syntax defined in java.net.JarURLConnection
URI uri = URI.create("jar:file:/directoryPath/file.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, Collections.<String, Object>emptyMap())) {
Path sourceURI = zipfs.getPath("/pathToDirectoryInsideZip/file.txt");
Path destinationURI = zipfs.getPath("/pathToDirectoryInsideZip/renamed.txt");
Files.move(sourceURI, destinationURI);
}
Using zip4j, I am modifying and re-writing the file headers inside of the central directory section to avoid rewriting the entire zip file:
ArrayList<FileHeader> FHs = (ArrayList<FileHeader>) zipFile.getFileHeaders();
FHs.get(0).setFileName("namename.mp4");
FHs.get(0).setFileNameLength("namename.mp4".getBytes("UTF-8").length);
zipFile.updateHeaders ();
//where updateHeaders is :
public void updateHeaders() throws ZipException, IOException {
checkZipModel();
if (this.zipModel == null) {
throw new ZipException("internal error: zip model is null");
}
if (Zip4jUtil.checkFileExists(file)) {
if (zipModel.isSplitArchive()) {
throw new ZipException("Zip file already exists. Zip file format does not allow updating split/spanned files");
}
}
long offset = zipModel.getEndCentralDirRecord().getOffsetOfStartOfCentralDir();
HeaderWriter headerWriter = new HeaderWriter();
SplitOutputStream splitOutputStream = new SplitOutputStream(new File(zipModel.getZipFile()), -1);
splitOutputStream.seek(offset);
headerWriter.finalizeZipFile(zipModel, splitOutputStream);
splitOutputStream.close();
}
The name field in the local file header section remains unchanged, so there will be a mismatch exception in this library.
It's tricky but maybe problematic, I don't know..

Opening Android resource file by URI raises FileNotFoundException

I am trying to get a URI to a resource in my res/raw/ directory. The goal is to give this URI to a VideoView, but this has been problematic, and I seem to be unable to open the file with test code.
I have the following test code:
String uri = "android.resource://com.my.package/" + R.raw.sample_video;
File inputFile = new File(uri);
try {
InputStream is = new FileInputStream(inputFile);
byte[] bytes = new byte[50];
is.read(bytes);
Log.d("test", new String(bytes));
} catch(IOException e) {
}
The new FileInputStream line throws a FileNotFoundException regardless of what variation i try on the URI, but every piece of evidence I see seems to agree that this is the correct form.
For reasons relating to the architecture of the project, the Resource methods that return an InputStream directly aren't an option here, so the URI is the only option that I can see.
What is going wrong? Am I mistaken in how to specify the URI for this file? Is this test code not representative of whether or not the VideoView will be able to read the file? If not, what is? Does this test code work for you (which would indicate that something must be wrong with my project configuration)?
To get the URI of sample_video in raw folder :
Uri videoUri = Uri.parse("android.resource://" + getPackageName() + "/"
+ R.raw.sample_video); //do not add any extension
To play the video :
videocontainer.setVideoURI(Uri.parse(videoUri));
videocontainer.start();
where videocontainer of type videoview.

Converting Java file:// URL to File(...) path, platform independent, including UNC paths

I am developing a platform independent application. I am receiving a file URL*.
On windows these are:
file:///Z:/folder%20to%20file/file.txt
file://host/folder%20to%20file/file.txt (an UNC path)
I am using new File(URI(urlOfDocument).getPath())which works fine with the first one and also on Unix, Linux, OS X, but does not work with UNC paths.
What is the standard way to convert file: URLs to File(..) paths, being compatible with Java 6?
......
*
Note: I am receiving theses URLs from OpenOffice / LibreOffice (XModel.getURL()).
Based on the hint and link provided in Simone Giannis' answer, this is my hack to fix this.
I am testing on uri.getAuthority(), because UNC path will report an Authority. This is a bug - so I rely on the existence of a bug, which is evil, but it apears as if this will stay forever (since Java 7 solves the problem in java.nio.Paths).
Note: In my context I will receive absolute paths. I have tested this on Windows and OS X.
(Still looking for a better way to do it)
package com.christianfries.test;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
public class UNCPathTest {
public static void main(String[] args) throws MalformedURLException, URISyntaxException {
UNCPathTest upt = new UNCPathTest();
upt.testURL("file://server/dir/file.txt"); // Windows UNC Path
upt.testURL("file:///Z:/dir/file.txt"); // Windows drive letter path
upt.testURL("file:///dir/file.txt"); // Unix (absolute) path
}
private void testURL(String urlString) throws MalformedURLException, URISyntaxException {
URL url = new URL(urlString);
System.out.println("URL is: " + url.toString());
URI uri = url.toURI();
System.out.println("URI is: " + uri.toString());
if(uri.getAuthority() != null && uri.getAuthority().length() > 0) {
// Hack for UNC Path
uri = (new URL("file://" + urlString.substring("file:".length()))).toURI();
}
File file = new File(uri);
System.out.println("File is: " + file.toString());
String parent = file.getParent();
System.out.println("Parent is: " + parent);
System.out.println("____________________________________________________________");
}
}
Building on #SotiriosDelimanolis's comment, here is a method to deal with URLs (such as file:...) and non-URLs (such as C:...), using Spring's FileSystemResource:
public FileSystemResource get(String file) {
try {
// First try to resolve as URL (file:...)
Path path = Paths.get(new URL(file).toURI());
FileSystemResource resource = new FileSystemResource(path.toFile());
return resource;
} catch (URISyntaxException | MalformedURLException e) {
// If given file string isn't an URL, fall back to using a normal file
return new FileSystemResource(file);
}
}
Java (at least 5 and 6, java 7 Paths solved most) has a problem with UNC and URI. Eclipse team wrapped it up here : http://wiki.eclipse.org/Eclipse/UNC_Paths
From java.io.File javadocs, the UNC prefix is "////", and java.net.URI handles file:////host/path (four slashes).
More details on why this happens and possible problems it causes in other URI and URL methods can be found in the list of bugs at the end of the link given above.
Using these informations, Eclipse team developed org.eclipse.core.runtime.URIUtil class, which source code can probably help out when dealing with UNC paths.
For Java 8 the following method works:
Form an URI from file URI string
Create a file from the URI (not directly from URI string, absolute URI string are not paths)
Refer, below code snippet
String fileURiString="file:///D:/etc/MySQL.txt";
URI fileURI=new URI(fileURiString);
File file=new File(fileURI);//File file=new File(fileURiString) - will generate exception
FileInputStream fis=new FileInputStream(file);
fis.close();
I hope (not exactly verified) that newer java brought nio package and Path. Hopefully it have it fixed:
String s="C:\\some\\ile.txt";
System.out.println(new File(s).toPath().toUri());

Categories