Files¶
Files and folders are addressed with FilePath and FolderPath, both of which always start with a
slash. Create them with the asFilePath() / asFolderPath() extension functions:
val file = "/Projects/welcome.txt".asFilePath()
val folder = "/Projects".asFolderPath()
val root = "/".asFolderPath()
Listing files¶
Lists all files and folders one level deep; nested content is not fetched.
try {
val items = service.listFiles("/".asFolderPath())
} catch (e: CloudBridgeException) {
// Handle...
}
Listing delta changes¶
Lists all file/folder changes since the last time this was called. Not supported by all services, see Cloud services for the support matrix.
try {
val result = service.getDelta(previousCursor)
val previouCursor = result.newCursor
val changes = result.changes
} catch (e: CloudBridgeException) {
// Handle...
}
Getting file or folder info¶
Fetches the metadata of a single file or folder. If nothing exists at the path, or the item has the
other type (a folder when asking for a file or the other way round), a NotFoundException is
thrown.
try {
val file: CloudFile = service.getFileInfo("/Projects/Welcome.txt".asFilePath())
val folder: CloudFolder = service.getFolderInfo("/Projects".asFolderPath())
} catch (e: CloudBridgeException) {
// Handle...
}
Calling getFolderInfo() for the root folder (/) throws an IllegalArgumentException.
Creating a folder¶
try {
service.createFolder("/Projects".asFolderPath())
} catch (e: CloudBridgeException) {
// Handle...
}
Creating a text file¶
try {
val file: CloudFile = service.createFile("/Projects/Welcome.txt".asFilePath(), "Hello world!")
println("Created ${file.id} at revision ${file.revision}")
} catch (e: CloudBridgeException) {
// Handle...
}
Updating a text file¶
try {
val file: CloudFile = service.updateFile(fileId, "Updated content")
println("Updated ${file.id} to revision ${file.revision}")
} catch (e: CloudBridgeException) {
// Handle...
}
Uploading binary or large files¶
For images, archives and other binary content, pass a function that opens a kotlinx.io.Source.
Files larger than 10 MB are automatically uploaded in chunks1.
try {
val localPath = Path("photo.jpg")
service.createFile(
path = localPath.name.asFilePath(),
source = { SystemFileSystem.source(localPath).buffered() },
sizeInBytes = SystemFileSystem.metadataOrNull(localPath)?.size,
mimeType = "image/jpeg",
onProgress = { bytesSent, totalBytes -> println("Sent $bytesSent of $totalBytes bytes") }
)
} catch (e: CloudBridgeException) {
// Handle...
}
- The function is called once per attempt, so an upload can be retried
after rate limiting. It must return a new
Sourceat the start of the content each time. ACloudBridgeException.SourceReadExceptionis thrown if it returns a source that was already read. - Each source is read until its end and then closed by the library.
sizeInBytesis optional, except for OneDrive files larger than 10 MB (throws aCloudBridgeException.IllegalArgumentExceptionif missing or not matching the content size in that case).mimeTypedefaults toapplication/octet-stream. Dropbox doesn't store MIME types and ignores it.onProgressis optional and useful to track how far uploads are progressing.totalBytesissizeInBytesif given, otherwise only known after the last chunk.- WebDAV has no chunked uploads, so the content is streamed in a single request and
onProgressis called once, when done. updateFile()has as similar signature ascreateFile().
Using an InputStream¶
Here's an example on how to use an InputStream on Android and desktop:
try {
val file = File("photo.jpg")
service.createFile(
path = file.name.asFilePath(),
source = { file.inputStream().asSource().buffered() },
sizeInBytes = file.length(),
mimeType = "image/jpeg"
)
} catch (e: CloudBridgeException) {
// Handle...
}
Downloading a file¶
try {
val content: String = service.downloadFile(fileId)
} catch (e: CloudBridgeException) {
// Handle...
}
Downloading binary or large files¶
For images, archives and other binary content, pass a kotlinx.io.Sink. The content is streamed
into it, so large files aren't held in memory. The sink is flushed, but not closed.
try {
SystemFileSystem.sink(Path("photo.jpg")).buffered().use { sink ->
service.downloadFile(fileId, sink)
}
} catch (e: CloudBridgeException) {
// Handle...
}
To get the content in memory instead, use a Buffer:
val buffer = Buffer()
service.downloadFile(fileId, buffer)
val bytes = buffer.readByteArray()
Moving or renaming a file or folder¶
To rename an item, move it within the same folder. If an item already exists at the new path, a
CloudBridgeException.ConflictException is thrown.
try {
// Rename/move a file
service.moveFile(fileId, "/Projects/New name.txt".asFilePath())
// Or a folder
service.moveFolder(folderId, "/Projects2".asFolderPath())
} catch (e: CloudBridgeException) {
// Handle...
}
On WebDAV, the id of an item is its path, so the returned item has a new id.
Deleting a file or folder¶
try {
service.delete(itemId)
} catch (e: CloudBridgeException) {
// Handle...
}
-
Chunk size is around 10 MB, which is "optimal for stable high speed connections" (https://learn.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0#best-practices). See the support matrix for details. ↩