Google Drive Java Api - update file in the folder. - java

i have a folder in the GoogleDrive. Its named 'lgc'. In it, i have a file info. I know the ID of the folder, but i dont know the ID of 'info' text file in it. I want to UPDATE the content of 'info' file, Conditions to update:
I dont want to change file name or title, only wanting to change its contents.
I dont want to use File ID for 'info' file. Using search Query, that will only result file with name as 'info'.
So, How do i find file without id and How do i Update it? I looked Google Developers website. but please help me, i didnt understood it.
tell me answer to following too: how can i do following?
Before Uploading a file, Check if any file with the same Title is present in Drive.
If present, delete present file and upload new file (Instead of Updating it)

Everything in Drive is keyed from the file ID, which is why you can end up multiple files sharing the same name. To modify content in Drive, you will have to at some stage work with the file ID, you cannot avoid that.
You can search for a file by name (title = 'info' and [parentID] in parents), but you will still need that query to return the file ID so that you can then update.
So your steps would be:
1) files.list where q is: title = 'info' and [parentID for lgc] in parents
2) If you get results, do a files.delete for each file ID returned (you could get more than 1)
3) files.insert for your new info file.
Some notes:
Drive doesn't support what you are trying to do as an atomic operation, which means there are some edge cases you will need to handle if you have a) the potential for multiple applications operate on the same account or b) multiple users operating on the same folder or c) the potential for a user themselves to create a file called 'info' in that lgc folder.
Step 1 may return more than a single file, so you should cater for that in step 2.
Another 'info' file may be created between Step 1 and Step 3, so after step 3 you should run the files.list search again to confirm that only your new file exists.

Related

How to prevent file wipe if an error occurs while writing to it?

This is an issue I have had in many applications.
I want to change the information inside a file, which has an outdated version.
In this instance, I am updating the file that records playlists after adding a song to a playlist. (For reference, I am creating an app for android.)
The problem is if I run this code:
FileOutputStream output = new FileOutputStream(file);
output.write(data.getBytes());
output.close();
And if an IOException occurs while trying to write to the file, the data is lost (since creating an instance of FileOutputStream empties the file). Is there a better method to do this, so if an IOException occurs, the old data remains intact? Or does this error only occur when the file is read-only, so I just need to check for that?
My only "work around" is to inform the user of the error, and give said user the correct data, which the user has to manually update. While this might work for a developer, there is a lot of issues that could occur if this happens. Additionally, in this case, the user doesn't have permission to edit the file themselves, so the "work around" doesn't work at all.
Sorry if someone else has asked this. I couldn't find a result when searching.
Thanks in advance!
One way you could ensure that you do not wipe the file is by creating a new file with a different name first. If writing that file succeeds, you could delete the old file and rename the new one.
There is the possibility that renaming fails. To be completely safe from that, your files could be named according to the time at which they are created. For instance, if your file is named save.dat, you could add the time at which the file was saved (from System.currentTimeMillis()) to the end of the file's name. Then, no matter what happens later (including failure to delete the old file or rename the new one), you can recover the most recent successful save. I have included a sample implementation below which represents the time as a 16-digit zero-padded hexadecimal number appended to the file extension. A file named save.dat will be instead saved as save.dat00000171ed431353 or something similar.
// name includes the file extension (i.e. "save.dat").
static File fileToSave(File directory, String name) {
return new File(directory, name + String.format("%016x", System.currentTimeMillis()));
}
// return the entire array if you need older versions for which deletion failed. This could be useful for attempting to purge any unnecessary older versions for instance.
static File fileToLoad(File directory, String name) {
File[] files = directory.listFiles((dir, n) -> n.startsWith(name));
Arrays.sort(files, Comparator.comparingLong((File file) -> Long.parseLong(file.getName().substring(name.length()), 16)).reversed());
return files[0];
}

how to upload an image from my android app to a specific folder on google drive

I'm using this code
to upload an image from my android app to the user's google drive account.
But how can I modify the code to upload the image to folder named "myFolder"?
meaning to that folder is exist and if not - create such folder and then upload the image there.
What you need to do in order to upload a file to a specific folder is to add the folder's id to the file parents (ref Docs for file.insert).
So the full things you need to do are:
Find the folder in drive
Create the insert request
Add the parent id to the file insert
Execute the insert request
Code
Find the Folder
Here you can opt for 2 ways: loop all the folders or search for it.
Faster and less resource heavy is to search the folder by name; to do so it's simple:
//Search by name and type folder
String qStr = "mimeType = 'application/vnd.google-apps.folder' and title = 'myFolder'";
//Get the list of Folders
FileList fList=service.files().list().setQ(qStr).execute();
//Check that the result is one folder
File folder;
if (fList.getItems().lenght==0){
folder=fList.getItems()[0];
}
More info about the possible search parameters.
Create the insert request is as in the sample
File file = service.files().insert(body, mediaContent);
before executing it we need to set the parent
file.setParents(Arrays.asList(new ParentReference().setId(folder.getFolderId())));
In the end execute the request
file.execute();
I haven't tested the code so there might be some typo here and there.

Deleting files via a 'ContentResolver' as opposed to deleting them via 'file.delete()'

I have just written a function in an android app that deletes a file using the standard 'File' class in Java. i.e:
String fileName= "/mnt/Gallery/Img001.jpg";
File file = new File(fileName);
file.delete();
While the above procedure is simple enough, I have been wondering if there is any advantage to doing the same via a 'ContentResolver'. Any advice would be appreciated.
------------------------------------------ EDIT ----------------------------------------
Here's an example of deleting a file via the Content Resolver. This example assumes the file being deleted is an image and that its 'id' is known.
long mediaId = 155; // NOTE: You would normally obtain this from the content provider!
Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri itemUri = ContentUris.withAppendedId(contentUri, mediaId);
int rows = getContentResolver().delete(itemUri, null, null);
String path = itemUri.getEncodedPath();
if(rows == 0)
{
Log.e("Example Code:","Could not delete "+path+" :(");
}
else
{
Log.d("Example Code:","Deleted "+path+ " ^_^");
}
Android's content provider framework has certain added advantages when compared to directly manipulating data.
You can think on the lines of 'Where does the file reside and who may be deleting it'.
Scenario 1
File resides on SD card (a path accessible by your app) and you app is deleting it.
Solution : Since the path is accessible to you, the java approach will work with a file Uri like:
file://mnt/sdcard/downloads/image.jpeg
Scenario 2
File resides in another app (say dropbox) and your app needs to delete the file.
Solution : This means that the file actually resides in the private storage of another app. A file: Uri will the above approach will give you access denied. So, your app will need to fetch a content Uri from the app containing the file and call into its content provider to delete.
fileUri = Uri.parse ("content : // " + packageContainingTheFile " + fileId); // replace this with Uri obtained from the app.
getContext().getContentResolver().delete (fileUri, null, null);
Scenario 3
File resides in your app's package directory i.e, under data/data/com.yourpackage/yourfolder/yourfile.xxx and your app is the only one deleting it.
Solution : Here, either of the above approaches will work since you have the access to delete the file.
Uri will look like:
file://data/data/yourpackage/folder/file.ext
The prime advantage of using content provider here is that you automatically gain the observer model. Content provider callbacks are a well defined entry point from where data is modified. Hence, its a desired place to notify others of changes using:
getContext().getContentResolver().notify(uri, null)
Assume you have views that show a listing of such file items. As soon as the delete is done, your can be notified.
Scenario 4
File resides in your app's package directory i.e, under data/data/com.yourpackage/yourfolder/yourfile.xxx and you want to expose the delete functionality to other apps.
Solution : This is similar to Scenario 1, just the other way round. Other apps cannot delete the file in your private storage with a Uri like
file://data/data/yourpackage/folder/file.ext // works just for your app
They will need to call in your content provider to do this with a Uri like.
content://providerAuthority/delete/id
which your content provider will need to map to file.ext absolute path.
Summary
To conclude, the use of content provider is necessary is some scenarios while optional in others. It largely depends on your app requirements. If you have views, CursorLoaders in place and want to be informed about updates or wish to expose deletion of your app data to other apps, content provider is the cleanest approach.

Java: Marking/Flagging a file

I would like to know whether or not there is some way of marking a file to identify whether or not the file contains x.
Consider the following example:
During a batch conversion process I am creating a log file which lists the success / failure of individual conversions.
So the process is as follows:
start conversion process
create log file named batch_XXX_yyyy_mm_dd.log
try to convert 'a'
write success to log file
try to convert 'b'
write success to log file
...
try to convert 'z'
write success to log file
close and persist log file
What I would like to be able to do is mark a file in some way that identifies whether any of the conversions logged in the file were unsuccessful.
I do not want to change the file name (visibly) and I do not want to open the file to check for a marker.
Does anyone have any ideas on how this could be achieved?
You can add file attributes in Java 7 through the java.nio.file.Files class.
So it would be possible to mark whether a file contains X using the Files.setAttribute() method:
Files.setAttribute( "path/to/file", "containsX", true );
And then check whether the file does contain X using the Files.getAttribute( ) method:
Files.getAttribute( "path/to/file", "containsX" )
If you are looking into say
file.log
create another file which will maintain this info say
file.log.status
Your status file can then contain all the information you need. It will be easier to get the status of conversion for all the files as well as easy to map back to original file given a status file.

Checking for a Valid Path when Uploading a File Using commons-fileupload

I'm working with some code that uploads an image from a form and stores it on our server. In Internet Explorer the user can enter a path manually, and I wonder how I can check that the file exists, i.e., that the user entered a valid path.
There's a FileItem object that's being used to check size (e.g., fileItem.getSize() < MAX_SIZE), and I wonder if a good approach would be to use size to check that the file exists. For example:
if (fileItem.getSize() == 0) {
// Somethings wrong -- invalid path.
} else {
// File exists -- valid path.
}
Any suggestions are appreciated. Thanks!
On the client, you cannot reliably read the text of a file upload control with script. IE8 and Opera10, for instance, will lie to you and provide a generic path containing "C:\fakepath\". This is done for privacy reasons.
On the server, you can do exactly as you've done, simply check to see that you actually got a file in the upload, and if so, then you can examine the file, determine if it matches your criteria.

Categories