feat(bindings/dart): add File.read and File.write with error mapping (#7473)

Add read/write async and sync methods to the Dart File class,
mirroring Rust Operator::read and Operator::write.

Changes:
- rust/src/api/opendal_api.rs: add read/read_sync/write/write_sync
  returning anyhow::Result so Rust errors surface as Dart exceptions
- rust/Cargo.toml: add anyhow = "1.0" dependency
- lib/opendal.dart: add File.read()/readSync()/write()/writeSync()
- tests/opendal_test.dart: add round-trip, missing-file throws, and
  overwrite semantics tests
- Regenerate FRB bindings for new methods

Depends on FRB 2.12.0 upgrade (PR A).

Scope: bindings/dart only.
AI-assisted: od-kimi-scout-050121.

Co-authored-by: tianyizhuang <tianyizhuang@tianyizhuangs-Mac-mini.local>
diff --git a/bindings/dart/lib/opendal.dart b/bindings/dart/lib/opendal.dart
index 1c7d730..47c6999 100644
--- a/bindings/dart/lib/opendal.dart
+++ b/bindings/dart/lib/opendal.dart
@@ -16,6 +16,7 @@
 // under the License.
 
 import 'dart:io' as io;
+import 'dart:typed_data';
 import 'package:system_info2/system_info2.dart';
 import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_io.dart';
 import 'src/rust/frb_generated.dart';
@@ -148,6 +149,22 @@
   void deleteSync() {
     _operator.deleteSync(path: path);
   }
+
+  Future<Uint8List> read() {
+    return _operator.read(path: path);
+  }
+
+  Uint8List readSync() {
+    return _operator.readSync(path: path);
+  }
+
+  Future<void> write(Uint8List data) {
+    return _operator.write(path: path, data: data);
+  }
+
+  void writeSync(Uint8List data) {
+    _operator.writeSync(path: path, data: data);
+  }
 }
 
 class Directory {
diff --git a/bindings/dart/lib/src/rust/api/opendal_api.dart b/bindings/dart/lib/src/rust/api/opendal_api.dart
index 9040eb5..640f033 100644
--- a/bindings/dart/lib/src/rust/api/opendal_api.dart
+++ b/bindings/dart/lib/src/rust/api/opendal_api.dart
@@ -56,6 +56,10 @@
       RustLib.instance.api
           .crateApiOpendalApiOperatorNew(scheme: scheme, map: map);
 
+  Future<Uint8List> read({required String path});
+
+  Uint8List readSync({required String path});
+
   Future<void> rename({required String from, required String to});
 
   void renameSync({required String from, required String to});
@@ -63,4 +67,8 @@
   Future<Metadata> stat({required String path});
 
   Metadata statSync({required String path});
+
+  Future<void> write({required String path, required List<int> data});
+
+  void writeSync({required String path, required List<int> data});
 }
diff --git a/bindings/dart/lib/src/rust/frb_generated.dart b/bindings/dart/lib/src/rust/frb_generated.dart
index 2936c2a..c34acb2 100644
--- a/bindings/dart/lib/src/rust/frb_generated.dart
+++ b/bindings/dart/lib/src/rust/frb_generated.dart
@@ -68,7 +68,7 @@
   String get codegenVersion => '2.12.0';
 
   @override
-  int get rustContentHash => 775125233;
+  int get rustContentHash => 798133092;
 
   static const kDefaultExternalLibraryLoaderConfig =
       ExternalLibraryLoaderConfig(
@@ -120,6 +120,12 @@
   Operator crateApiOpendalApiOperatorNew(
       {required String scheme, required Map<String, String> map});
 
+  Future<Uint8List> crateApiOpendalApiOperatorRead(
+      {required Operator that, required String path});
+
+  Uint8List crateApiOpendalApiOperatorReadSync(
+      {required Operator that, required String path});
+
   Future<void> crateApiOpendalApiOperatorRename(
       {required Operator that, required String from, required String to});
 
@@ -132,6 +138,12 @@
   Metadata crateApiOpendalApiOperatorStatSync(
       {required Operator that, required String path});
 
+  Future<void> crateApiOpendalApiOperatorWrite(
+      {required Operator that, required String path, required List<int> data});
+
+  void crateApiOpendalApiOperatorWriteSync(
+      {required Operator that, required String path, required List<int> data});
+
   RustArcIncrementStrongCountFnType
       get rust_arc_increment_strong_count_Metadata;
 
@@ -577,6 +589,61 @@
       );
 
   @override
+  Future<Uint8List> crateApiOpendalApiOperatorRead(
+      {required Operator that, required String path}) {
+    return handler.executeNormal(NormalTask(
+      callFfi: (port_) {
+        final serializer = SseSerializer(generalizedFrbRustBinding);
+        sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOperator(
+            that, serializer);
+        sse_encode_String(path, serializer);
+        pdeCallFfi(generalizedFrbRustBinding, serializer,
+            funcId: 17, port: port_);
+      },
+      codec: SseCodec(
+        decodeSuccessData: sse_decode_list_prim_u_8_strict,
+        decodeErrorData: sse_decode_AnyhowException,
+      ),
+      constMeta: kCrateApiOpendalApiOperatorReadConstMeta,
+      argValues: [that, path],
+      apiImpl: this,
+    ));
+  }
+
+  TaskConstMeta get kCrateApiOpendalApiOperatorReadConstMeta =>
+      const TaskConstMeta(
+        debugName: "Operator_read",
+        argNames: ["that", "path"],
+      );
+
+  @override
+  Uint8List crateApiOpendalApiOperatorReadSync(
+      {required Operator that, required String path}) {
+    return handler.executeSync(SyncTask(
+      callFfi: () {
+        final serializer = SseSerializer(generalizedFrbRustBinding);
+        sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOperator(
+            that, serializer);
+        sse_encode_String(path, serializer);
+        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 18)!;
+      },
+      codec: SseCodec(
+        decodeSuccessData: sse_decode_list_prim_u_8_strict,
+        decodeErrorData: sse_decode_AnyhowException,
+      ),
+      constMeta: kCrateApiOpendalApiOperatorReadSyncConstMeta,
+      argValues: [that, path],
+      apiImpl: this,
+    ));
+  }
+
+  TaskConstMeta get kCrateApiOpendalApiOperatorReadSyncConstMeta =>
+      const TaskConstMeta(
+        debugName: "Operator_read_sync",
+        argNames: ["that", "path"],
+      );
+
+  @override
   Future<void> crateApiOpendalApiOperatorRename(
       {required Operator that, required String from, required String to}) {
     return handler.executeNormal(NormalTask(
@@ -587,7 +654,7 @@
         sse_encode_String(from, serializer);
         sse_encode_String(to, serializer);
         pdeCallFfi(generalizedFrbRustBinding, serializer,
-            funcId: 17, port: port_);
+            funcId: 19, port: port_);
       },
       codec: SseCodec(
         decodeSuccessData: sse_decode_unit,
@@ -615,7 +682,7 @@
             that, serializer);
         sse_encode_String(from, serializer);
         sse_encode_String(to, serializer);
-        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 18)!;
+        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 20)!;
       },
       codec: SseCodec(
         decodeSuccessData: sse_decode_unit,
@@ -643,7 +710,7 @@
             that, serializer);
         sse_encode_String(path, serializer);
         pdeCallFfi(generalizedFrbRustBinding, serializer,
-            funcId: 19, port: port_);
+            funcId: 21, port: port_);
       },
       codec: SseCodec(
         decodeSuccessData:
@@ -671,7 +738,7 @@
         sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOperator(
             that, serializer);
         sse_encode_String(path, serializer);
-        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 20)!;
+        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 22)!;
       },
       codec: SseCodec(
         decodeSuccessData:
@@ -690,6 +757,63 @@
         argNames: ["that", "path"],
       );
 
+  @override
+  Future<void> crateApiOpendalApiOperatorWrite(
+      {required Operator that, required String path, required List<int> data}) {
+    return handler.executeNormal(NormalTask(
+      callFfi: (port_) {
+        final serializer = SseSerializer(generalizedFrbRustBinding);
+        sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOperator(
+            that, serializer);
+        sse_encode_String(path, serializer);
+        sse_encode_list_prim_u_8_loose(data, serializer);
+        pdeCallFfi(generalizedFrbRustBinding, serializer,
+            funcId: 23, port: port_);
+      },
+      codec: SseCodec(
+        decodeSuccessData: sse_decode_unit,
+        decodeErrorData: sse_decode_AnyhowException,
+      ),
+      constMeta: kCrateApiOpendalApiOperatorWriteConstMeta,
+      argValues: [that, path, data],
+      apiImpl: this,
+    ));
+  }
+
+  TaskConstMeta get kCrateApiOpendalApiOperatorWriteConstMeta =>
+      const TaskConstMeta(
+        debugName: "Operator_write",
+        argNames: ["that", "path", "data"],
+      );
+
+  @override
+  void crateApiOpendalApiOperatorWriteSync(
+      {required Operator that, required String path, required List<int> data}) {
+    return handler.executeSync(SyncTask(
+      callFfi: () {
+        final serializer = SseSerializer(generalizedFrbRustBinding);
+        sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOperator(
+            that, serializer);
+        sse_encode_String(path, serializer);
+        sse_encode_list_prim_u_8_loose(data, serializer);
+        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 24)!;
+      },
+      codec: SseCodec(
+        decodeSuccessData: sse_decode_unit,
+        decodeErrorData: sse_decode_AnyhowException,
+      ),
+      constMeta: kCrateApiOpendalApiOperatorWriteSyncConstMeta,
+      argValues: [that, path, data],
+      apiImpl: this,
+    ));
+  }
+
+  TaskConstMeta get kCrateApiOpendalApiOperatorWriteSyncConstMeta =>
+      const TaskConstMeta(
+        debugName: "Operator_write_sync",
+        argNames: ["that", "path", "data"],
+      );
+
   RustArcIncrementStrongCountFnType
       get rust_arc_increment_strong_count_Metadata => wire
           .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata;
@@ -707,6 +831,12 @@
           .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOperator;
 
   @protected
+  AnyhowException dco_decode_AnyhowException(dynamic raw) {
+    // Codec=Dco (DartCObject based), see doc to use other codecs
+    return AnyhowException(raw as String);
+  }
+
+  @protected
   Metadata
       dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           dynamic raw) {
@@ -780,6 +910,12 @@
   }
 
   @protected
+  List<int> dco_decode_list_prim_u_8_loose(dynamic raw) {
+    // Codec=Dco (DartCObject based), see doc to use other codecs
+    return raw as List<int>;
+  }
+
+  @protected
   Uint8List dco_decode_list_prim_u_8_strict(dynamic raw) {
     // Codec=Dco (DartCObject based), see doc to use other codecs
     return raw as Uint8List;
@@ -841,6 +977,13 @@
   }
 
   @protected
+  AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer) {
+    // Codec=Sse (Serialization based), see doc to use other codecs
+    var inner = sse_decode_String(deserializer);
+    return AnyhowException(inner);
+  }
+
+  @protected
   Metadata
       sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           SseDeserializer deserializer) {
@@ -922,6 +1065,13 @@
   }
 
   @protected
+  List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer) {
+    // Codec=Sse (Serialization based), see doc to use other codecs
+    var len_ = sse_decode_i_32(deserializer);
+    return deserializer.buffer.getUint8List(len_);
+  }
+
+  @protected
   Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer) {
     // Codec=Sse (Serialization based), see doc to use other codecs
     var len_ = sse_decode_i_32(deserializer);
@@ -1002,6 +1152,13 @@
   }
 
   @protected
+  void sse_encode_AnyhowException(
+      AnyhowException self, SseSerializer serializer) {
+    // Codec=Sse (Serialization based), see doc to use other codecs
+    sse_encode_String(self.message, serializer);
+  }
+
+  @protected
   void
       sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           Metadata self, SseSerializer serializer) {
@@ -1082,6 +1239,15 @@
   }
 
   @protected
+  void sse_encode_list_prim_u_8_loose(
+      List<int> self, SseSerializer serializer) {
+    // Codec=Sse (Serialization based), see doc to use other codecs
+    sse_encode_i_32(self.length, serializer);
+    serializer.buffer
+        .putUint8List(self is Uint8List ? self : Uint8List.fromList(self));
+  }
+
+  @protected
   void sse_encode_list_prim_u_8_strict(
       Uint8List self, SseSerializer serializer) {
     // Codec=Sse (Serialization based), see doc to use other codecs
@@ -1266,6 +1432,12 @@
   bool existsSync({required String path}) => RustLib.instance.api
       .crateApiOpendalApiOperatorExistsSync(that: this, path: path);
 
+  Future<Uint8List> read({required String path}) => RustLib.instance.api
+      .crateApiOpendalApiOperatorRead(that: this, path: path);
+
+  Uint8List readSync({required String path}) => RustLib.instance.api
+      .crateApiOpendalApiOperatorReadSync(that: this, path: path);
+
   Future<void> rename({required String from, required String to}) =>
       RustLib.instance.api
           .crateApiOpendalApiOperatorRename(that: this, from: from, to: to);
@@ -1279,4 +1451,12 @@
 
   Metadata statSync({required String path}) => RustLib.instance.api
       .crateApiOpendalApiOperatorStatSync(that: this, path: path);
+
+  Future<void> write({required String path, required List<int> data}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorWrite(that: this, path: path, data: data);
+
+  void writeSync({required String path, required List<int> data}) => RustLib
+      .instance.api
+      .crateApiOpendalApiOperatorWriteSync(that: this, path: path, data: data);
 }
diff --git a/bindings/dart/lib/src/rust/frb_generated.io.dart b/bindings/dart/lib/src/rust/frb_generated.io.dart
index ea65c86..18f21f3 100644
--- a/bindings/dart/lib/src/rust/frb_generated.io.dart
+++ b/bindings/dart/lib/src/rust/frb_generated.io.dart
@@ -25,6 +25,9 @@
       ._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOperatorPtr;
 
   @protected
+  AnyhowException dco_decode_AnyhowException(dynamic raw);
+
+  @protected
   Metadata
       dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           dynamic raw);
@@ -67,6 +70,9 @@
   BigInt dco_decode_box_autoadd_u_64(dynamic raw);
 
   @protected
+  List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
+
+  @protected
   Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
 
   @protected
@@ -94,6 +100,9 @@
   BigInt dco_decode_usize(dynamic raw);
 
   @protected
+  AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
+
+  @protected
   Metadata
       sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           SseDeserializer deserializer);
@@ -137,6 +146,9 @@
   BigInt sse_decode_box_autoadd_u_64(SseDeserializer deserializer);
 
   @protected
+  List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
+
+  @protected
   Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
 
   @protected
@@ -169,6 +181,10 @@
   int sse_decode_i_32(SseDeserializer deserializer);
 
   @protected
+  void sse_encode_AnyhowException(
+      AnyhowException self, SseSerializer serializer);
+
+  @protected
   void
       sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           Metadata self, SseSerializer serializer);
@@ -212,6 +228,9 @@
   void sse_encode_box_autoadd_u_64(BigInt self, SseSerializer serializer);
 
   @protected
+  void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);
+
+  @protected
   void sse_encode_list_prim_u_8_strict(
       Uint8List self, SseSerializer serializer);
 
diff --git a/bindings/dart/lib/src/rust/frb_generated.web.dart b/bindings/dart/lib/src/rust/frb_generated.web.dart
index c2a3b5c..c08ea8a 100644
--- a/bindings/dart/lib/src/rust/frb_generated.web.dart
+++ b/bindings/dart/lib/src/rust/frb_generated.web.dart
@@ -27,6 +27,9 @@
       .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerOperator;
 
   @protected
+  AnyhowException dco_decode_AnyhowException(dynamic raw);
+
+  @protected
   Metadata
       dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           dynamic raw);
@@ -69,6 +72,9 @@
   BigInt dco_decode_box_autoadd_u_64(dynamic raw);
 
   @protected
+  List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
+
+  @protected
   Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
 
   @protected
@@ -96,6 +102,9 @@
   BigInt dco_decode_usize(dynamic raw);
 
   @protected
+  AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
+
+  @protected
   Metadata
       sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           SseDeserializer deserializer);
@@ -139,6 +148,9 @@
   BigInt sse_decode_box_autoadd_u_64(SseDeserializer deserializer);
 
   @protected
+  List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
+
+  @protected
   Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
 
   @protected
@@ -171,6 +183,10 @@
   int sse_decode_i_32(SseDeserializer deserializer);
 
   @protected
+  void sse_encode_AnyhowException(
+      AnyhowException self, SseSerializer serializer);
+
+  @protected
   void
       sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerMetadata(
           Metadata self, SseSerializer serializer);
@@ -214,6 +230,9 @@
   void sse_encode_box_autoadd_u_64(BigInt self, SseSerializer serializer);
 
   @protected
+  void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);
+
+  @protected
   void sse_encode_list_prim_u_8_strict(
       Uint8List self, SseSerializer serializer);
 
diff --git a/bindings/dart/rust/Cargo.toml b/bindings/dart/rust/Cargo.toml
index 176221a..84c15d5 100644
--- a/bindings/dart/rust/Cargo.toml
+++ b/bindings/dart/rust/Cargo.toml
@@ -21,6 +21,7 @@
 version = "0.1.0"
 
 [dependencies]
+anyhow = "1.0"
 flutter_rust_bridge = "=2.12.0"
 opendal = { path = "../../../core", features = [
   "blocking",
diff --git a/bindings/dart/rust/src/api/opendal_api.rs b/bindings/dart/rust/src/api/opendal_api.rs
index 70add34..1f3b155 100644
--- a/bindings/dart/rust/src/api/opendal_api.rs
+++ b/bindings/dart/rust/src/api/opendal_api.rs
@@ -90,6 +90,28 @@
     pub fn rename_sync(&self, from: String, to: String) -> () {
         self.blocking_op.rename(&from, &to).unwrap()
     }
+
+    pub async fn read(&self, path: String) -> anyhow::Result<Vec<u8>> {
+        let buf = self.async_op.read(&path).await.map_err(|e| anyhow::anyhow!(e))?;
+        Ok(buf.to_vec())
+    }
+
+    #[frb(sync)]
+    pub fn read_sync(&self, path: String) -> anyhow::Result<Vec<u8>> {
+        let buf = self.blocking_op.read(&path).map_err(|e| anyhow::anyhow!(e))?;
+        Ok(buf.to_vec())
+    }
+
+    pub async fn write(&self, path: String, data: Vec<u8>) -> anyhow::Result<()> {
+        self.async_op.write(&path, data).await.map_err(|e| anyhow::anyhow!(e))?;
+        Ok(())
+    }
+
+    #[frb(sync)]
+    pub fn write_sync(&self, path: String, data: Vec<u8>) -> anyhow::Result<()> {
+        self.blocking_op.write(&path, data).map_err(|e| anyhow::anyhow!(e))?;
+        Ok(())
+    }
 }
 
 #[frb(opaque)]
diff --git a/bindings/dart/rust/src/frb_generated.rs b/bindings/dart/rust/src/frb_generated.rs
index d26fd8f..e3e5639 100644
--- a/bindings/dart/rust/src/frb_generated.rs
+++ b/bindings/dart/rust/src/frb_generated.rs
@@ -39,7 +39,7 @@
     default_rust_auto_opaque = RustAutoOpaqueMoi,
 );
 pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0";
-pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 775125233;
+pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 798133092;
 
 // Section: executor
 
@@ -848,6 +848,114 @@
         },
     )
 }
+fn wire__crate__api__opendal_api__Operator_read_impl(
+    port_: flutter_rust_bridge::for_generated::MessagePort,
+    ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
+    rust_vec_len_: i32,
+    data_len_: i32,
+) {
+    FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
+        flutter_rust_bridge::for_generated::TaskInfo {
+            debug_name: "Operator_read",
+            port: Some(port_),
+            mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
+        },
+        move || {
+            let message = unsafe {
+                flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
+                    ptr_,
+                    rust_vec_len_,
+                    data_len_,
+                )
+            };
+            let mut deserializer =
+                flutter_rust_bridge::for_generated::SseDeserializer::new(message);
+            let api_that = <RustOpaqueMoi<
+                flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>,
+            >>::sse_decode(&mut deserializer);
+            let api_path = <String>::sse_decode(&mut deserializer);
+            deserializer.end();
+            move |context| async move {
+                transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
+                    (move || async move {
+                        let mut api_that_guard = None;
+                        let decode_indices_ =
+                            flutter_rust_bridge::for_generated::lockable_compute_decode_order(
+                                vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new(
+                                    &api_that, 0, false,
+                                )],
+                            );
+                        for i in decode_indices_ {
+                            match i {
+                                0 => {
+                                    api_that_guard =
+                                        Some(api_that.lockable_decode_async_ref().await)
+                                }
+                                _ => unreachable!(),
+                            }
+                        }
+                        let api_that_guard = api_that_guard.unwrap();
+                        let output_ok =
+                            crate::api::opendal_api::Operator::read(&*api_that_guard, api_path)
+                                .await?;
+                        Ok(output_ok)
+                    })()
+                    .await,
+                )
+            }
+        },
+    )
+}
+fn wire__crate__api__opendal_api__Operator_read_sync_impl(
+    ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
+    rust_vec_len_: i32,
+    data_len_: i32,
+) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
+    FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::<flutter_rust_bridge::for_generated::SseCodec, _>(
+        flutter_rust_bridge::for_generated::TaskInfo {
+            debug_name: "Operator_read_sync",
+            port: None,
+            mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync,
+        },
+        move || {
+            let message = unsafe {
+                flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
+                    ptr_,
+                    rust_vec_len_,
+                    data_len_,
+                )
+            };
+            let mut deserializer =
+                flutter_rust_bridge::for_generated::SseDeserializer::new(message);
+            let api_that = <RustOpaqueMoi<
+                flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>,
+            >>::sse_decode(&mut deserializer);
+            let api_path = <String>::sse_decode(&mut deserializer);
+            deserializer.end();
+            transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
+                (move || {
+                    let mut api_that_guard = None;
+                    let decode_indices_ =
+                        flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![
+                            flutter_rust_bridge::for_generated::LockableOrderInfo::new(
+                                &api_that, 0, false,
+                            ),
+                        ]);
+                    for i in decode_indices_ {
+                        match i {
+                            0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()),
+                            _ => unreachable!(),
+                        }
+                    }
+                    let api_that_guard = api_that_guard.unwrap();
+                    let output_ok =
+                        crate::api::opendal_api::Operator::read_sync(&*api_that_guard, api_path)?;
+                    Ok(output_ok)
+                })(),
+            )
+        },
+    )
+}
 fn wire__crate__api__opendal_api__Operator_rename_impl(
     port_: flutter_rust_bridge::for_generated::MessagePort,
     ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
@@ -1075,6 +1183,122 @@
         },
     )
 }
+fn wire__crate__api__opendal_api__Operator_write_impl(
+    port_: flutter_rust_bridge::for_generated::MessagePort,
+    ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
+    rust_vec_len_: i32,
+    data_len_: i32,
+) {
+    FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
+        flutter_rust_bridge::for_generated::TaskInfo {
+            debug_name: "Operator_write",
+            port: Some(port_),
+            mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
+        },
+        move || {
+            let message = unsafe {
+                flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
+                    ptr_,
+                    rust_vec_len_,
+                    data_len_,
+                )
+            };
+            let mut deserializer =
+                flutter_rust_bridge::for_generated::SseDeserializer::new(message);
+            let api_that = <RustOpaqueMoi<
+                flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>,
+            >>::sse_decode(&mut deserializer);
+            let api_path = <String>::sse_decode(&mut deserializer);
+            let api_data = <Vec<u8>>::sse_decode(&mut deserializer);
+            deserializer.end();
+            move |context| async move {
+                transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
+                    (move || async move {
+                        let mut api_that_guard = None;
+                        let decode_indices_ =
+                            flutter_rust_bridge::for_generated::lockable_compute_decode_order(
+                                vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new(
+                                    &api_that, 0, false,
+                                )],
+                            );
+                        for i in decode_indices_ {
+                            match i {
+                                0 => {
+                                    api_that_guard =
+                                        Some(api_that.lockable_decode_async_ref().await)
+                                }
+                                _ => unreachable!(),
+                            }
+                        }
+                        let api_that_guard = api_that_guard.unwrap();
+                        let output_ok = crate::api::opendal_api::Operator::write(
+                            &*api_that_guard,
+                            api_path,
+                            api_data,
+                        )
+                        .await?;
+                        Ok(output_ok)
+                    })()
+                    .await,
+                )
+            }
+        },
+    )
+}
+fn wire__crate__api__opendal_api__Operator_write_sync_impl(
+    ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
+    rust_vec_len_: i32,
+    data_len_: i32,
+) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
+    FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::<flutter_rust_bridge::for_generated::SseCodec, _>(
+        flutter_rust_bridge::for_generated::TaskInfo {
+            debug_name: "Operator_write_sync",
+            port: None,
+            mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync,
+        },
+        move || {
+            let message = unsafe {
+                flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
+                    ptr_,
+                    rust_vec_len_,
+                    data_len_,
+                )
+            };
+            let mut deserializer =
+                flutter_rust_bridge::for_generated::SseDeserializer::new(message);
+            let api_that = <RustOpaqueMoi<
+                flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>,
+            >>::sse_decode(&mut deserializer);
+            let api_path = <String>::sse_decode(&mut deserializer);
+            let api_data = <Vec<u8>>::sse_decode(&mut deserializer);
+            deserializer.end();
+            transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
+                (move || {
+                    let mut api_that_guard = None;
+                    let decode_indices_ =
+                        flutter_rust_bridge::for_generated::lockable_compute_decode_order(vec![
+                            flutter_rust_bridge::for_generated::LockableOrderInfo::new(
+                                &api_that, 0, false,
+                            ),
+                        ]);
+                    for i in decode_indices_ {
+                        match i {
+                            0 => api_that_guard = Some(api_that.lockable_decode_sync_ref()),
+                            _ => unreachable!(),
+                        }
+                    }
+                    let api_that_guard = api_that_guard.unwrap();
+                    let output_ok = crate::api::opendal_api::Operator::write_sync(
+                        &*api_that_guard,
+                        api_path,
+                        api_data,
+                    )?;
+                    Ok(output_ok)
+                })(),
+            )
+        },
+    )
+}
 
 // Section: related_funcs
 
@@ -1087,6 +1311,14 @@
 
 // Section: dart2rust
 
+impl SseDecode for flutter_rust_bridge::for_generated::anyhow::Error {
+    // Codec=Sse (Serialization based), see doc to use other codecs
+    fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
+        let mut inner = <String>::sse_decode(deserializer);
+        return flutter_rust_bridge::for_generated::anyhow::anyhow!("{}", inner);
+    }
+}
+
 impl SseDecode for Metadata {
     // Codec=Sse (Serialization based), see doc to use other codecs
     fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -1260,10 +1492,12 @@
         14 => {
             wire__crate__api__opendal_api__Operator_exists_impl(port, ptr, rust_vec_len, data_len)
         }
-        17 => {
+        17 => wire__crate__api__opendal_api__Operator_read_impl(port, ptr, rust_vec_len, data_len),
+        19 => {
             wire__crate__api__opendal_api__Operator_rename_impl(port, ptr, rust_vec_len, data_len)
         }
-        19 => wire__crate__api__opendal_api__Operator_stat_impl(port, ptr, rust_vec_len, data_len),
+        21 => wire__crate__api__opendal_api__Operator_stat_impl(port, ptr, rust_vec_len, data_len),
+        23 => wire__crate__api__opendal_api__Operator_write_impl(port, ptr, rust_vec_len, data_len),
         _ => unreachable!(),
     }
 }
@@ -1300,8 +1534,10 @@
         13 => wire__crate__api__opendal_api__Operator_delete_sync_impl(ptr, rust_vec_len, data_len),
         15 => wire__crate__api__opendal_api__Operator_exists_sync_impl(ptr, rust_vec_len, data_len),
         16 => wire__crate__api__opendal_api__Operator_new_impl(ptr, rust_vec_len, data_len),
-        18 => wire__crate__api__opendal_api__Operator_rename_sync_impl(ptr, rust_vec_len, data_len),
-        20 => wire__crate__api__opendal_api__Operator_stat_sync_impl(ptr, rust_vec_len, data_len),
+        18 => wire__crate__api__opendal_api__Operator_read_sync_impl(ptr, rust_vec_len, data_len),
+        20 => wire__crate__api__opendal_api__Operator_rename_sync_impl(ptr, rust_vec_len, data_len),
+        22 => wire__crate__api__opendal_api__Operator_stat_sync_impl(ptr, rust_vec_len, data_len),
+        24 => wire__crate__api__opendal_api__Operator_write_sync_impl(ptr, rust_vec_len, data_len),
         _ => unreachable!(),
     }
 }
@@ -1338,6 +1574,13 @@
     }
 }
 
+impl SseEncode for flutter_rust_bridge::for_generated::anyhow::Error {
+    // Codec=Sse (Serialization based), see doc to use other codecs
+    fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
+        <String>::sse_encode(format!("{:?}", self), serializer);
+    }
+}
+
 impl SseEncode for Metadata {
     // Codec=Sse (Serialization based), see doc to use other codecs
     fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
diff --git a/bindings/dart/tests/opendal_test.dart b/bindings/dart/tests/opendal_test.dart
index 693b08a..516167d 100644
--- a/bindings/dart/tests/opendal_test.dart
+++ b/bindings/dart/tests/opendal_test.dart
@@ -1,4 +1,5 @@
 import 'package:test/test.dart';
+import 'dart:typed_data';
 import '../lib/opendal.dart';
 
 void main() {
@@ -36,6 +37,39 @@
         expect(meta.isFile, false);
         expect(meta.isDirectory, true);
       });
+
+      test('File read/write round-trip', () async {
+        final storage = await Storage.init(schemeStr: "memory", map: {"root": "/tmp"});
+        final File = storage.initFile();
+        var testFile = File("roundtrip.txt");
+        final data = Uint8List.fromList([1, 2, 3, 4, 5]);
+
+        await testFile.write(data);
+        expect(await testFile.exists(), true);
+
+        final readData = await testFile.read();
+        expect(readData, equals(data));
+      });
+
+      test('File read from missing path throws', () async {
+        final storage = await Storage.init(schemeStr: "memory", map: {"root": "/tmp"});
+        final File = storage.initFile();
+        var missingFile = File("nonexistent.txt");
+
+        expect(() async => await missingFile.read(), throwsA(anything));
+      });
+
+      test('File overwrite semantics', () async {
+        final storage = await Storage.init(schemeStr: "memory", map: {"root": "/tmp"});
+        final File = storage.initFile();
+        var testFile = File("overwrite.txt");
+
+        await testFile.write(Uint8List.fromList([1, 2, 3]));
+        await testFile.write(Uint8List.fromList([4, 5]));
+
+        final readData = await testFile.read();
+        expect(readData, equals(Uint8List.fromList([4, 5])));
+      });
     });
   });
 }