Files
You can use Kinvey to store and retrieve binary files of size up to 5TB. Files can be of any format.
The files are automatically enabled for download using a Content Delivery Network (CDN) for massive scale and performance.
Kinvey does not directly serve or accept files. Instead, the Kinvey Files API works by providing a short-lived URL to a third-party cloud storage service from which file(s) can be uploaded or downloaded. Currently, the third-party service used is Google Cloud Storage.
You would typically use the Files API to upload and download:
- images
- video files
- other application-specific files.
Uploading
The library's File
API supports uploading a java.io.File
directly as well as streaming content from an InputStream
.
java.io.File
To upload a file, use myClient.file().upload()
. Pass the file content as the first argument, followed by an UploadProgressListener
for callbacks.
_id
, you should avoid values that are exactly 12 or 24 symbols in length. Such values are automatically converted to BSON ObjectID and are not stored as strings in the database, which can interfere with querying and other operations.
To ensure that no items with 12 or 24 symbols long _id
are stored in the collection, you can create a pre-save hook that either prevents saving such items, or appends an additional symbol (for example, underscore) to the _id
:
if (_id.length === 12 || _id.length === 24) {
_id += "_";
}
import com.kinvey.java.core.UploadProgressListener;
...
try{
java.io.File file = new java.io.File(getFilesDir(), "chicken_fried_waffles.txt");
file.createNewFile();
myClient.file().uploadBlocking(file, new UploaderProgressListener() {
@Override
public void onSuccess(Void result) {
System.out.println("upload success!");
}
@Override
public void onFailure(Throwable error) {
System.out.println("upload progress change!");
}
@Override
public void progressChanged(MediaHttpUploader uploader) throws IOException {
System.out.println("upload progress change -> " + uploader.getUploadState());
}
});
}catch(IOException e){
System.out.println("Couldn't upload! -> " + e);
e.printStackTrace();
}
Optionally, you can use a FileMetaData object as the first parameter to save additional metadata. This lets you set ACLs, mark files as public, and set any other custom attributes your app may need.
import com.kinvey.java.model.FileMetaData;
import com.kinvey.java.model.KinveyMetaData.AccessControlList;
...
FileMetaData metadata = new FileMetaData("myFileID"); //create the FileMetaData object
metadata.setPublic(true); //set the file to be pubicly accesible
metadata.setAcl(new KinveyMetaData.AccessControlList().setGloballyReadable(true)); //allow all users to see this file
metadata.setFileName("chicken_fried_waffles.txt");
try{
java.io.File file = new java.io.File(getFilesDir(), "chicken_fried_waffles.txt");
file.createNewFile();
myClient.file().uploadBlocking(metadata, file, new UploaderProgressListener() {
@Override
public void onSuccess(Void result) {
System.out.println("upload success!");
}
@Override
public void onFailure(Throwable error) {
System.out.println("upload progress change!");
}
@Override
public void progressChanged(MediaHttpUploader uploader) throws IOException {
System.out.println("upload progress change -> " + uploader.getUploadState());
}
});
}catch(IOException e){
System.out.println("Couldn't upload! -> " + e);
e.printStackTrace();
}
InputStream
Alternatively you can upload a file from an input stream.
try{
FileInputStream fIn = new FileInputStream(new File ("eats_bacon.mpg"));
myClient.file().uploadBlocking("myFileID", fIn, new UploaderProgressListener() {
@Override
public void onSuccess(Void result) {
System.out.println("upload success!");
}
@Override
public void onFailure(Throwable error) {
System.out.println("upload progress change!");
}
@Override
public void progressChanged(MediaHttpUploader uploader) throws IOException {
System.out.println("upload progress change -> " + uploader.getUploadState());
}
});
}catch(IOException e){
System.out.println("Couldn't upload! -> " + e);
e.printStackTrace();
}
You can also provide a FileMetaData object as the first argument when streaming from an InputStream
.
import com.kinvey.java.model.FileMetaData;
import com.kinvey.java.model.KinveyMetaData.AccessControlList;
...
FileMetaData metadata = new FileMetaData("myFileID"); //create the FileMetaData object
metadata.setPublic(true); //set the file to be pubicly accesible
metadata.setAcl(new KinveyMetaData.AccessControlList().setGloballyReadable(true)); //allow all users to see this file
metadata.setFileName("eats_bacon.mpg");
try{
FileInputStream fIn = new FileInputStream(new File ("eats_bacon.mpg"));
myClient.file().uploadBlocking(metadata, fIn, new UploaderProgressListener() {
@Override
public void onSuccess(Void result) {
System.out.println("upload success!");
}
@Override
public void onFailure(Throwable error) {
System.out.println("upload progress change!");
}
@Override
public void progressChanged(MediaHttpUploader uploader) throws IOException {
System.out.println("upload progress change -> " + uploader.getUploadState());
}
});
}catch(IOException e){
System.out.println("Couldn't upload! -> " + e);
e.printStackTrace();
}
Uploading publicly readable files
Use the method myFileMetaData.setPublic(true)
if you want to upload a publicly-readable file. This means that the download link to the file will not expire until you delete the file through Kinvey.
import com.kinvey.java.model.FileMetaData;
...
FileMetaData myFileMetaData = new FileMetaData("myFileID"); //create the FileMetaData object
myFileMetaData.setPublic(true); //set the file to be pubicly accesible
metadata.setFileName("chicken_fried_waffles.txt");
try{
java.io.File file = new java.io.File(getFilesDir(), "chicken_fried_waffles.txt");
file.createNewFile();
myClient.file().uploadBlocking(myFileMetaData, file, new UploaderProgressListener() {
@Override
public void onSuccess(Void result) {
System.out.println("upload success!");
}
@Override
public void onFailure(Throwable error) {
System.out.println("upload progress change!");
}
@Override
public void progressChanged(MediaHttpUploader uploader) throws IOException {
System.out.println("upload progress change -> " + uploader.getUploadState());
}
});
}catch(IOException e){
System.out.println("Couldn't upload! -> " + e);
e.printStackTrace();
}
Downloading
For downloading files to an OutputStream
, you can open a file output stream, by name, then feed the
file output stream to the file download.
FileOutputStream fos= new FileOutputStream("mug.png");
try{
myClient.file().downloadBlocking("myFileID", fos, new DownloadProgressListener() {
@Override
public void onSuccess(Void result) {
System.out.println("download success!");
}
@Override
public void onFailure(Throwable error) {
System.out.println("download progress change!");
}
@Override
public void progressChanged(MediaHttpDownloader downloader) throws IOException {
System.out.println("download progress change -> " + downloader.getUploadState());
}
});
}catch(IOException e){
System.out.println("Couldn't download! -> " + e);
e.printStackTrace();
}
Specifying a custom expiration time
Files can also be retrieved by a query, and you can optionally set a custom expiration time (in seconds) if you need the temporary URL to last longer (or shorter) than one hour.
import com.kinvey.java.Query;
...
FileOutputStream fos= new FileOutputStream("mug.png");
Query q = new Query() //create a new query
q.equals("ttl_in_seconds", 3600); //set a new ttl for the download URL
try{
myClient.file().downloadBlocking("myFileID", q, fos, new DownloadProgressListener() {
@Override
public void onSuccess(Void result) {
System.out.println("download success!");
}
@Override
public void onFailure(Throwable error) {
System.out.println("download progress change!");
}
@Override
public void progressChanged(MediaHttpDownloader downloader) throws IOException {
System.out.println("download progress change -> " + downloader.getUploadState());
}
});
}catch(IOException e){
System.out.println("Couldn't download! -> " + e);
e.printStackTrace();
}
Deleting
You can permanently remove a file using the delete()
method, which takes the unique file _id
.
try{
KinveyDeleteResponse delete = myJavaClient.file().deleteBlocking("myFileID").execute();
}catch(IOException e){
System.out.println("Couldn't delete! -> " + e);
e.printStackTrace();
}
Deletion can also be performed by providing a FileMetaData
object which must contain an _id
.
try{
KinveyDeleteResponse delete = myJavaClient.file().deleteBlocking(new FileMetaData("myFileId")).execute();
}catch(IOException e){
System.out.println("Couldn't delete! -> " + e);
e.printStackTrace();
}
Client
, for File
requests you do not have to call execute()
(except for delete()), however you must pass an UploadProgressListener
or DownloadProgressListener
as the final arguement.