diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9eb5955..e58d836 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.1.0]
+
+### 21-01-2026
+
+### Feature
+
+- Allow reading parts of a file with `offset` and `length`.
+
## [1.0.3]
### 13-01-2026
diff --git a/package.json b/package.json
index e6d6a64..ad03548 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "com.outsystems.plugins.filesystem",
- "version": "1.0.3",
+ "version": "1.1.0",
"private": true,
"dependencies": {},
"scripts": {
diff --git a/packages/cordova-plugin/README.md b/packages/cordova-plugin/README.md
index 2911581..467c992 100644
--- a/packages/cordova-plugin/README.md
+++ b/packages/cordova-plugin/README.md
@@ -266,11 +266,13 @@ Copy a file or directory
#### ReadFileOptions
-| Prop | Type | Description | Since |
-| --------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
-| **`path`** | string | The path of the file to read | 1.0.0 |
-| **`directory`** | Directory | The `Directory` to read the file from | 1.0.0 |
-| **`encoding`** | Encoding | The encoding to read the file in, if not provided, data is read as binary and returned as base64 encoded. Pass Encoding.UTF8 to read data as string | 1.0.0 |
+| Prop | Type | Description | Default | Since |
+| --------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | ----- |
+| **`path`** | string | The path of the file to read | | 1.0.0 |
+| **`directory`** | Directory | The `Directory` to read the file from | | 1.0.0 |
+| **`encoding`** | Encoding | The encoding to read the file in, if not provided, data is read as binary and returned as base64 encoded. Pass Encoding.UTF8 to read data as string | | 1.0.0 |
+| **`offset`** | number | The offset to start reading the file from, in bytes. Native only (not available in web). Can be used in conjunction with length to partially read files. | 0 | 1.1.0 |
+| **`length`** | number | The length of data to read, in bytes. Any non-positive value means to read to the end of the file. Native only (not available in web). Can be used in conjunction with offset to partially read files. | -1 | 1.1.0 |
#### ReadFileInChunksOptions
diff --git a/packages/cordova-plugin/android/OSFileErrors.kt b/packages/cordova-plugin/android/OSFileErrors.kt
index 1f4bad8..4677c83 100644
--- a/packages/cordova-plugin/android/OSFileErrors.kt
+++ b/packages/cordova-plugin/android/OSFileErrors.kt
@@ -97,5 +97,7 @@ fun Throwable.toFilesystemError(method: OSFileMethod): OSFileErrors.ErrorInfo =
is IONFILEExceptions.CopyRenameFailed.NoParentDirectory ->
OSFileErrors.missingParentDirectories
+ is IllegalArgumentException -> OSFileErrors.invalidInputMethod(method.methodName)
+
else -> OSFileErrors.operationFailed(method.methodName, this.localizedMessage ?: "")
}
\ No newline at end of file
diff --git a/packages/cordova-plugin/android/OSFileOptions.kt b/packages/cordova-plugin/android/OSFileOptions.kt
index 817f218..367a45c 100644
--- a/packages/cordova-plugin/android/OSFileOptions.kt
+++ b/packages/cordova-plugin/android/OSFileOptions.kt
@@ -1,5 +1,6 @@
package com.outsystems.plugins.file
+import io.ionic.libs.ionfilesystemlib.model.IONFILEConstants
import io.ionic.libs.ionfilesystemlib.model.IONFILEEncoding
import io.ionic.libs.ionfilesystemlib.model.IONFILEFolderType
import io.ionic.libs.ionfilesystemlib.model.IONFILEReadInChunksOptions
@@ -13,6 +14,8 @@ import org.json.JSONObject
private const val INPUT_PATH = "path"
private const val INPUT_DIRECTORY = "directory"
private const val INPUT_ENCODING = "encoding"
+private const val INPUT_OFFSET = "offset"
+private const val INPUT_LENGTH = "length"
private const val INPUT_CHUNK_SIZE = "chunkSize"
private const val INPUT_DATA = "data"
private const val INPUT_RECURSIVE = "recursive"
@@ -53,7 +56,15 @@ internal fun JSONObject.getReadFileOptions(): OSFileReadOptions? {
try {
val uri = getSingleIONFILEUri() ?: return null
val encoding = IONFILEEncoding.fromEncodingName(optString(INPUT_ENCODING))
- return OSFileReadOptions(uri = uri, options = IONFILEReadOptions(encoding))
+ val offsetAndLength = getOffsetAndLength()
+ return OSFileReadOptions(
+ uri = uri,
+ options = IONFILEReadOptions(
+ encoding,
+ offset = offsetAndLength.first,
+ length = offsetAndLength.second
+ )
+ )
} catch (ex: JSONException) {
return null
}
@@ -67,9 +78,16 @@ internal fun JSONObject.getReadFileInChunksOptions(): OSFileReadInChunksOptions?
val uri = getSingleIONFILEUri() ?: return null
val encoding = IONFILEEncoding.fromEncodingName(optString(INPUT_ENCODING))
val chunkSize = getInt(INPUT_CHUNK_SIZE).takeIf { it > 0 } ?: return null
+ val offsetAndLength = getOffsetAndLength()
return OSFileReadInChunksOptions(
uri = uri,
- options = IONFILEReadInChunksOptions(encoding = encoding, chunkSize = chunkSize)
+ options =
+ IONFILEReadInChunksOptions(
+ encoding = encoding,
+ chunkSize = chunkSize,
+ offset = offsetAndLength.first,
+ length = offsetAndLength.second
+ )
)
} catch (ex: JSONException) {
return null
@@ -146,6 +164,11 @@ internal fun JSONObject.getSingleIONFILEUri(): IONFILEUri.Unresolved? {
}
}
+private fun JSONObject.getOffsetAndLength(): Pair = Pair(
+ optInt(INPUT_OFFSET, 0).takeIf { it >= 0 } ?: 0,
+ optInt(INPUT_LENGTH, -1).takeIf { it > 0 } ?: IONFILEConstants.LENGTH_READ_TIL_EOF
+)
+
private fun unresolvedUri(path: String, directoryAlias: String?) = IONFILEUri.Unresolved(
parentFolder = IONFILEFolderType.fromStringAlias(directoryAlias),
uriPath = path
diff --git a/packages/cordova-plugin/android/build.gradle b/packages/cordova-plugin/android/build.gradle
index c6bca92..f4baf72 100644
--- a/packages/cordova-plugin/android/build.gradle
+++ b/packages/cordova-plugin/android/build.gradle
@@ -17,7 +17,7 @@ allprojects {
}
dependencies{
- implementation("io.ionic.libs:ionfilesystem-android:1.0.0@aar")
+ implementation("io.ionic.libs:ionfilesystem-android:1.1.0@aar")
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
diff --git a/packages/cordova-plugin/android/libs/IONFilesystemLib-debug.aar b/packages/cordova-plugin/android/libs/IONFilesystemLib-debug.aar
deleted file mode 100644
index 45d90b9..0000000
Binary files a/packages/cordova-plugin/android/libs/IONFilesystemLib-debug.aar and /dev/null differ
diff --git a/packages/cordova-plugin/dist/definitions.d.ts b/packages/cordova-plugin/dist/definitions.d.ts
index 7db4f87..fccd2a7 100644
--- a/packages/cordova-plugin/dist/definitions.d.ts
+++ b/packages/cordova-plugin/dist/definitions.d.ts
@@ -198,6 +198,25 @@ export interface ReadFileOptions {
* @since 1.0.0
*/
encoding?: Encoding;
+ /**
+ * The offset to start reading the file from, in bytes.
+ * Native only (not available in web).
+ * Can be used in conjunction with length to partially read files.
+ *
+ * @since 1.1.0
+ * @default 0
+ */
+ offset?: number;
+ /**
+ * The length of data to read, in bytes.
+ * Any non-positive value means to read to the end of the file.
+ * Native only (not available in web).
+ * Can be used in conjunction with offset to partially read files.
+ *
+ * @since 1.1.0
+ * @default -1
+ */
+ length?: number;
}
export interface ReadFileInChunksOptions extends ReadFileOptions {
/**
diff --git a/packages/cordova-plugin/ios/OSFileOperation.swift b/packages/cordova-plugin/ios/OSFileOperation.swift
index 7711a5a..767b8b1 100644
--- a/packages/cordova-plugin/ios/OSFileOperation.swift
+++ b/packages/cordova-plugin/ios/OSFileOperation.swift
@@ -3,8 +3,8 @@ import IONFilesystemLib
enum OSFileOperation {
// Read Operations
- case readFile(url: URL, encoding: IONFILEEncoding)
- case readFileInChunks(url: URL, encoding: IONFILEEncoding, chunkSize: Int)
+ case readFile(url: URL, encoding: IONFILEEncoding, offset: Int, length: Int)
+ case readFileInChunks(url: URL, encoding: IONFILEEncoding, chunkSize: Int, offset: Int, length: Int)
case readdir(url: URL)
case stat(url: URL)
case getUri(url: URL)
diff --git a/packages/cordova-plugin/ios/OSFileOperationExecutor.swift b/packages/cordova-plugin/ios/OSFileOperationExecutor.swift
index bb92ca5..4aa43bc 100644
--- a/packages/cordova-plugin/ios/OSFileOperationExecutor.swift
+++ b/packages/cordova-plugin/ios/OSFileOperationExecutor.swift
@@ -19,11 +19,11 @@ class OSFileOperationExecutor {
var resultData: PluginResultData?
switch operation {
- case .readFile(let url, let encoding):
- let fullData = try service.readEntireFile(atURL: url, withEncoding: encoding).textValue
+ case .readFile(let url, let encoding, let offset, let length):
+ let fullData = try service.readEntireFile(atURL: url, withEncoding: encoding, andOffset: offset, andLength: length).textValue
resultData = [OSFileConstants.ResultDataKey.data: fullData]
- case .readFileInChunks(let url, let encoding, let chunkSize):
- try processFileInChunks(at: url, withEncoding: encoding, chunkSize: chunkSize, for: operation, command)
+ case .readFileInChunks(let url, let encoding, let chunkSize, let offset, let length):
+ try processFileInChunks(at: url, withEncoding: encoding, chunkSize: chunkSize, offset: offset, length: length, for: operation, command)
return
case .write(let url, let encodingMapper, let recursive):
try service.saveFile(atURL: url, withEncodingAndData: encodingMapper, includeIntermediateDirectories: recursive)
@@ -61,9 +61,9 @@ class OSFileOperationExecutor {
}
private extension OSFileOperationExecutor {
- func processFileInChunks(at url: URL, withEncoding encoding: IONFILEEncoding, chunkSize: Int, for operation: OSFileOperation, _ command: CDVInvokedUrlCommand) throws {
+ func processFileInChunks(at url: URL, withEncoding encoding: IONFILEEncoding, chunkSize: Int, offset: Int, length: Int, for operation: OSFileOperation, _ command: CDVInvokedUrlCommand) throws {
let chunkSizeToUse = chunkSizeToUse(basedOn: chunkSize, and: encoding)
- try service.readFileInChunks(atURL: url, withEncoding: encoding, andChunkSize: chunkSizeToUse)
+ try service.readFileInChunks(atURL: url, withEncoding: encoding, andChunkSize: chunkSizeToUse, andOffset: offset, andLength: length)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
@@ -87,8 +87,8 @@ private extension OSFileOperationExecutor {
var path = ""
var method: OSFileMethod = OSFileMethod.getUri
switch operation {
- case .readFile(let url, _): path = url.absoluteString; method = .readFile
- case .readFileInChunks(let url, _, _): path = url.absoluteString; method = .readFileInChunks
+ case .readFile(let url, _, _, _): path = url.absoluteString; method = .readFile
+ case .readFileInChunks(let url, _, _, _, _): path = url.absoluteString; method = .readFileInChunks
case .write(let url, _, _): path = url.absoluteString; method = .writeFile
case .append(let url, _, _): path = url.absoluteString; method = .appendFile
case .delete(let url): path = url.absoluteString; method = .deleteFile
diff --git a/packages/cordova-plugin/ios/OSFilePlugin.swift b/packages/cordova-plugin/ios/OSFilePlugin.swift
index df51025..b414078 100644
--- a/packages/cordova-plugin/ios/OSFilePlugin.swift
+++ b/packages/cordova-plugin/ios/OSFilePlugin.swift
@@ -24,7 +24,7 @@ private extension OSFilePlugin {
}
performSinglePathOperation(command, options) {
- .readFile(url: $0, encoding: options.encoding)
+ .readFile(url: $0, encoding: options.encoding, offset: options.offset, length: options.length)
}
}
@@ -35,7 +35,7 @@ private extension OSFilePlugin {
}
performSinglePathOperation(command, options) {
- .readFileInChunks(url: $0, encoding: options.encoding, chunkSize: options.chunkSize)
+ .readFileInChunks(url: $0, encoding: options.encoding, chunkSize: options.chunkSize, offset: options.offset, length: options.length)
}
}
diff --git a/packages/cordova-plugin/ios/OSSinglePathFileOptions.swift b/packages/cordova-plugin/ios/OSSinglePathFileOptions.swift
index a7284ac..1fec840 100644
--- a/packages/cordova-plugin/ios/OSSinglePathFileOptions.swift
+++ b/packages/cordova-plugin/ios/OSSinglePathFileOptions.swift
@@ -41,9 +41,13 @@ class IONSinglePathRecursiveFileOptions: OSSinglePathFileOptions {
class IONReadFileOptions: OSSinglePathFileOptions {
let encoding: IONFILEEncoding
+ let offset: Int
+ let length: Int
enum CodingKeys: CodingKey {
case encoding
+ case offset
+ case length
}
required init(from decoder: any Decoder) throws {
@@ -51,6 +55,16 @@ class IONReadFileOptions: OSSinglePathFileOptions {
let encodingText = try container.decodeIfPresent(String.self, forKey: .encoding)
encoding = .create(from: encodingText)
+ if let decodedOffset = try container.decodeIfPresent(Int.self, forKey: .offset) {
+ offset = decodedOffset
+ } else {
+ offset = 0
+ }
+ if let decodedLength = try container.decodeIfPresent(Int.self, forKey: .length) {
+ length = decodedLength
+ } else {
+ length = -1
+ }
try super.init(from: decoder)
}
diff --git a/packages/cordova-plugin/package.json b/packages/cordova-plugin/package.json
index 309f29c..e965202 100644
--- a/packages/cordova-plugin/package.json
+++ b/packages/cordova-plugin/package.json
@@ -1,7 +1,7 @@
{
"name": "com.outsystems.plugins.filesystem",
"displayName": "Filesystem",
- "version": "1.0.1",
+ "version": "1.1.0",
"description": "Filesystem plugin for Cordova",
"scripts": {
"lint": "npm run eslint && npm run prettier -- --check",
diff --git a/packages/cordova-plugin/src/definitions.ts b/packages/cordova-plugin/src/definitions.ts
index 0b8b042..dea0d25 100644
--- a/packages/cordova-plugin/src/definitions.ts
+++ b/packages/cordova-plugin/src/definitions.ts
@@ -222,6 +222,27 @@ export interface ReadFileOptions {
* @since 1.0.0
*/
encoding?: Encoding;
+
+ /**
+ * The offset to start reading the file from, in bytes.
+ * Native only (not available in web).
+ * Can be used in conjunction with length to partially read files.
+ *
+ * @since 1.1.0
+ * @default 0
+ */
+ offset?: number;
+
+ /**
+ * The length of data to read, in bytes.
+ * Any non-positive value means to read to the end of the file.
+ * Native only (not available in web).
+ * Can be used in conjunction with offset to partially read files.
+ *
+ * @since 1.1.0
+ * @default -1
+ */
+ length?: number;
}
export interface ReadFileInChunksOptions extends ReadFileOptions {
diff --git a/plugin.xml b/plugin.xml
index 8819b50..7929d38 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -1,5 +1,5 @@
-
+
OSFilePlugin
OutSystems' cordova geolocation plugin
OutSystems Inc
@@ -60,8 +60,8 @@
-
+
-
+
\ No newline at end of file