This is an automated email from the ASF dual-hosted git repository.

sgilmore pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new d261a824f4 GH-42146:  [MATLAB] Add IPC `RecordBatchFileReader` and 
`RecordBatchFileWriter` MATLAB classes (#42201)
d261a824f4 is described below

commit d261a824f4e322e6dcc01948c3a2769690d11b3d
Author: Sarah Gilmore <[email protected]>
AuthorDate: Thu Jun 20 09:21:48 2024 -0400

    GH-42146:  [MATLAB] Add IPC `RecordBatchFileReader` and 
`RecordBatchFileWriter` MATLAB classes (#42201)
    
    ### Rationale for this change
    
    To enable initial IPC I/O support in the MATLAB interface, we should add a 
`RecordBatchFileReader` class and a `RecordBatchFileWriter` class.
    
    ### What changes are included in this PR?
    
    1. Added a new `arrow.io.ipc.RecordBatchFileWriter` class.
    2. Added a new `arrow.io.ipc.RecordBatchFileReader` class.
    
    **Example**
    
    ```matlab
    >> city = ["Boston" "Seattle" "Denver" "Juno" "Anchorage" "Chicago"]';
    >> daylength = duration(["15:17:01" "15:59:16" "14:59:14" "19:21:23" 
"14:18:24" "15:13:39"])';
    >> matlabTable = table(city, daylength, VariableNames=["City", 
"DayLength"]);
    >> recordBatch1 = arrow.recordBatch(matlabTable(1:4, :))
    >> recordBatch2 = arrow.recordBatch(matlabTable(5:end, :));
    
    >> writer = arrow.io.ipc.RecordBatchFileWriter("daylight.arrow", 
recordBatch1.Schema);
    >> writer.writeRecordBatch(recordBatch1);
    >> writer.writeRecordBatch(recordBatch2);
    >> writer.close();
    
    >> reader = arrow.io.ipc.RecordBatchFileReader("daylight.arrow");
    
    reader =
    
      RecordBatchFileReader with properties:
    
        NumRecordBatches: 2
                  Schema: [1×1 arrow.tabular.Schema]
    
    >> reader.Schema
    
    ans =
    
      Arrow Schema with 2 fields:
    
        City: String | DayLength: Time64
    
    >> rb1 = reader.read(1);
    >> isequal(rb1, recordBatch1)
    
    ans =
    
      logical
    
       1
    
    >> rb2 = reader.read(2);
    >> isequal(rb2, recordBatch2)
    
    ans =
    
      logical
    
       1
    
    ```
    
    ### Are these changes tested?
    
    Yes.  Added two new test files:
    
    1. `arrow/matlab/test/io/ipc/tRecordBatchFileWriter.m`
    2. `arrow/matlab/test/io/ipc/tRecordBatchFileReader.m`
    
    ### Are there any user-facing changes?
    
    Yes. Users can now serialize `RecordBatch`es and `Table`s to files using 
the Arrow IPC data format as well as read in `RecordBatch`es from Arrow IPC 
data files.
    
    ### Future Directions
    
    1. Add `RecordBatchStreamWriter` and `RecordBatchStreamReader`
    2. Expose options for 
[controlling](https://github.com/apache/arrow/blob/main/cpp/src/arrow/ipc/options.h)
  IPC reading and writing in MATLAB.
    3. Add more methods to `RecordBatchFileReader` to read in multiple record 
batches at once as well as importing the data as an Arrow `Table`.
    
    * GitHub Issue: #42146
    
    Authored-by: Sarah Gilmore <[email protected]>
    Signed-off-by: Sarah Gilmore <[email protected]>
---
 matlab/src/cpp/arrow/matlab/error/error.h          |   7 +
 .../io/ipc/proxy/record_batch_file_reader.cc       | 128 +++++++++++++
 .../matlab/io/ipc/proxy/record_batch_file_reader.h |  44 +++++
 .../io/ipc/proxy/record_batch_file_writer.cc       | 107 +++++++++++
 .../matlab/io/ipc/proxy/record_batch_file_writer.h |  42 ++++
 matlab/src/cpp/arrow/matlab/proxy/factory.cc       |   4 +
 .../matlab/+arrow/+io/+ipc/RecordBatchFileReader.m |  64 +++++++
 .../matlab/+arrow/+io/+ipc/RecordBatchFileWriter.m |  77 ++++++++
 matlab/test/arrow/io/ipc/tRecordBatchFileReader.m  | 184 ++++++++++++++++++
 matlab/test/arrow/io/ipc/tRecordBatchFileWriter.m  | 211 +++++++++++++++++++++
 matlab/tools/cmake/BuildMatlabArrowInterface.cmake |   4 +-
 11 files changed, 871 insertions(+), 1 deletion(-)

diff --git a/matlab/src/cpp/arrow/matlab/error/error.h 
b/matlab/src/cpp/arrow/matlab/error/error.h
index 58c43d8843..e5a5df6f4b 100644
--- a/matlab/src/cpp/arrow/matlab/error/error.h
+++ b/matlab/src/cpp/arrow/matlab/error/error.h
@@ -242,5 +242,12 @@ static const char* 
ARRAY_SLICE_FAILED_TO_CREATE_ARRAY_PROXY =
     "arrow:array:slice:FailedToCreateArrayProxy";
 static const char* C_EXPORT_FAILED = "arrow:c:export:ExportFailed";
 static const char* C_IMPORT_FAILED = "arrow:c:import:ImportFailed";
+static const char* IPC_RECORD_BATCH_WRITE_FAILED =
+    "arrow:io:ipc:FailedToWriteRecordBatch";
+static const char* IPC_RECORD_BATCH_WRITE_CLOSE_FAILED = 
"arrow:io:ipc:CloseFailed";
+static const char* IPC_RECORD_BATCH_READER_OPEN_FAILED =
+    "arrow:io:ipc:FailedToOpenRecordBatchReader";
+static const char* IPC_RECORD_BATCH_READ_INVALID_INDEX = 
"arrow:io:ipc:InvalidIndex";
+static const char* IPC_RECORD_BATCH_READ_FAILED = "arrow:io:ipc:ReadFailed";
 
 }  // namespace arrow::matlab::error
diff --git 
a/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_reader.cc 
b/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_reader.cc
new file mode 100644
index 0000000000..9db5d6a9ba
--- /dev/null
+++ b/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_reader.cc
@@ -0,0 +1,128 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "arrow/matlab/io/ipc/proxy/record_batch_file_reader.h"
+#include "arrow/io/file.h"
+#include "arrow/matlab/error/error.h"
+#include "arrow/matlab/tabular/proxy/record_batch.h"
+#include "arrow/matlab/tabular/proxy/schema.h"
+#include "arrow/util/utf8.h"
+
+#include "libmexclass/proxy/ProxyManager.h"
+
+namespace arrow::matlab::io::ipc::proxy {
+
+namespace {
+libmexclass::error::Error makeInvalidNumericIndexError(const int32_t 
matlab_index,
+                                                       const int32_t 
num_batches) {
+  std::stringstream error_message_stream;
+  error_message_stream << "Invalid record batch index: ";
+  error_message_stream << matlab_index;
+  error_message_stream
+      << ". Record batch index must be between 1 and the number of record 
batches (";
+  error_message_stream << num_batches;
+  error_message_stream << ").";
+  return libmexclass::error::Error{error::IPC_RECORD_BATCH_READ_INVALID_INDEX,
+                                   error_message_stream.str()};
+}
+}  // namespace
+
+RecordBatchFileReader::RecordBatchFileReader(
+    const std::shared_ptr<arrow::ipc::RecordBatchFileReader> reader)
+    : reader{std::move(reader)} {
+  REGISTER_METHOD(RecordBatchFileReader, getNumRecordBatches);
+  REGISTER_METHOD(RecordBatchFileReader, getSchema);
+  REGISTER_METHOD(RecordBatchFileReader, readRecordBatchAtIndex);
+}
+
+libmexclass::proxy::MakeResult RecordBatchFileReader::make(
+    const libmexclass::proxy::FunctionArguments& constructor_arguments) {
+  namespace mda = ::matlab::data;
+  using RecordBatchFileReaderProxy = 
arrow::matlab::io::ipc::proxy::RecordBatchFileReader;
+
+  const mda::StructArray opts = constructor_arguments[0];
+
+  const mda::StringArray filename_mda = opts[0]["Filename"];
+  const auto filename_utf16 = std::u16string(filename_mda[0]);
+  MATLAB_ASSIGN_OR_ERROR(const auto filename_utf8,
+                         arrow::util::UTF16StringToUTF8(filename_utf16),
+                         error::UNICODE_CONVERSION_ERROR_ID);
+
+  MATLAB_ASSIGN_OR_ERROR(auto input_stream, 
arrow::io::ReadableFile::Open(filename_utf8),
+                         error::FAILED_TO_OPEN_FILE_FOR_WRITE);
+
+  MATLAB_ASSIGN_OR_ERROR(auto reader,
+                         arrow::ipc::RecordBatchFileReader::Open(input_stream),
+                         error::IPC_RECORD_BATCH_READER_OPEN_FAILED);
+
+  return std::make_shared<RecordBatchFileReaderProxy>(std::move(reader));
+}
+
+void RecordBatchFileReader::getNumRecordBatches(
+    libmexclass::proxy::method::Context& context) {
+  namespace mda = ::matlab::data;
+
+  mda::ArrayFactory factory;
+  const auto num_batches = reader->num_record_batches();
+  context.outputs[0] = factory.createScalar(num_batches);
+}
+
+void RecordBatchFileReader::getSchema(libmexclass::proxy::method::Context& 
context) {
+  namespace mda = ::matlab::data;
+  using SchemaProxy = arrow::matlab::tabular::proxy::Schema;
+
+  auto schema = reader->schema();
+
+  auto schema_proxy = std::make_shared<SchemaProxy>(std::move(schema));
+  const auto schema_proxy_id =
+      libmexclass::proxy::ProxyManager::manageProxy(schema_proxy);
+
+  mda::ArrayFactory factory;
+  const auto schema_proxy_id_mda = factory.createScalar(schema_proxy_id);
+  context.outputs[0] = schema_proxy_id_mda;
+}
+
+void RecordBatchFileReader::readRecordBatchAtIndex(
+    libmexclass::proxy::method::Context& context) {
+  namespace mda = ::matlab::data;
+  using RecordBatchProxy = arrow::matlab::tabular::proxy::RecordBatch;
+
+  mda::StructArray opts = context.inputs[0];
+  const mda::TypedArray<int32_t> matlab_index_mda = opts[0]["Index"];
+
+  const auto matlab_index = matlab_index_mda[0];
+  const auto num_record_batches = reader->num_record_batches();
+  if (matlab_index < 1 || matlab_index > num_record_batches) {
+    context.error = makeInvalidNumericIndexError(matlab_index, 
num_record_batches);
+    return;
+  }
+  const auto arrow_index = matlab_index - 1;
+
+  MATLAB_ASSIGN_OR_ERROR_WITH_CONTEXT(const auto record_batch,
+                                      reader->ReadRecordBatch(arrow_index), 
context,
+                                      error::IPC_RECORD_BATCH_READ_FAILED);
+
+  auto record_batch_proxy = 
std::make_shared<RecordBatchProxy>(std::move(record_batch));
+  const auto record_batch_proxy_id =
+      libmexclass::proxy::ProxyManager::manageProxy(record_batch_proxy);
+
+  mda::ArrayFactory factory;
+  const auto record_batch_proxyy_id_mda = 
factory.createScalar(record_batch_proxy_id);
+  context.outputs[0] = record_batch_proxyy_id_mda;
+}
+
+}  // namespace arrow::matlab::io::ipc::proxy
\ No newline at end of file
diff --git 
a/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_reader.h 
b/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_reader.h
new file mode 100644
index 0000000000..41d5c9a158
--- /dev/null
+++ b/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_reader.h
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include "arrow/ipc/reader.h"
+#include "libmexclass/proxy/Proxy.h"
+
+namespace arrow::matlab::io::ipc::proxy {
+
+class RecordBatchFileReader : public libmexclass::proxy::Proxy {
+ public:
+  RecordBatchFileReader(std::shared_ptr<arrow::ipc::RecordBatchFileReader> 
reader);
+
+  ~RecordBatchFileReader() = default;
+
+  static libmexclass::proxy::MakeResult make(
+      const libmexclass::proxy::FunctionArguments& constructor_arguments);
+
+ protected:
+  std::shared_ptr<arrow::ipc::RecordBatchFileReader> reader;
+
+  void getNumRecordBatches(libmexclass::proxy::method::Context& context);
+
+  void getSchema(libmexclass::proxy::method::Context& context);
+
+  void readRecordBatchAtIndex(libmexclass::proxy::method::Context& context);
+};
+
+}  // namespace arrow::matlab::io::ipc::proxy
\ No newline at end of file
diff --git 
a/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_writer.cc 
b/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_writer.cc
new file mode 100644
index 0000000000..ed1052e0a8
--- /dev/null
+++ b/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_writer.cc
@@ -0,0 +1,107 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "arrow/matlab/io/ipc/proxy/record_batch_file_writer.h"
+#include "arrow/io/file.h"
+#include "arrow/matlab/error/error.h"
+#include "arrow/matlab/tabular/proxy/record_batch.h"
+#include "arrow/matlab/tabular/proxy/schema.h"
+#include "arrow/matlab/tabular/proxy/table.h"
+#include "arrow/util/utf8.h"
+
+#include "libmexclass/proxy/ProxyManager.h"
+
+namespace arrow::matlab::io::ipc::proxy {
+
+RecordBatchFileWriter::RecordBatchFileWriter(
+    const std::shared_ptr<arrow::ipc::RecordBatchWriter> writer)
+    : writer{std::move(writer)} {
+  REGISTER_METHOD(RecordBatchFileWriter, close);
+  REGISTER_METHOD(RecordBatchFileWriter, writeRecordBatch);
+  REGISTER_METHOD(RecordBatchFileWriter, writeTable);
+}
+
+libmexclass::proxy::MakeResult RecordBatchFileWriter::make(
+    const libmexclass::proxy::FunctionArguments& constructor_arguments) {
+  namespace mda = ::matlab::data;
+  using RecordBatchFileWriterProxy = 
arrow::matlab::io::ipc::proxy::RecordBatchFileWriter;
+  using SchemaProxy = arrow::matlab::tabular::proxy::Schema;
+
+  const mda::StructArray opts = constructor_arguments[0];
+
+  const mda::StringArray filename_mda = opts[0]["Filename"];
+  const auto filename_utf16 = std::u16string(filename_mda[0]);
+  MATLAB_ASSIGN_OR_ERROR(const auto filename_utf8,
+                         arrow::util::UTF16StringToUTF8(filename_utf16),
+                         error::UNICODE_CONVERSION_ERROR_ID);
+
+  const mda::TypedArray<uint64_t> arrow_schema_proxy_id_mda = 
opts[0]["SchemaProxyID"];
+  auto proxy = 
libmexclass::proxy::ProxyManager::getProxy(arrow_schema_proxy_id_mda[0]);
+  auto arrow_schema_proxy = std::static_pointer_cast<SchemaProxy>(proxy);
+  auto arrow_schema = arrow_schema_proxy->unwrap();
+
+  MATLAB_ASSIGN_OR_ERROR(auto output_stream,
+                         arrow::io::FileOutputStream::Open(filename_utf8),
+                         error::FAILED_TO_OPEN_FILE_FOR_WRITE);
+
+  MATLAB_ASSIGN_OR_ERROR(auto writer,
+                         arrow::ipc::MakeFileWriter(output_stream, 
arrow_schema),
+                         "arrow:matlab:MakeFailed");
+
+  return std::make_shared<RecordBatchFileWriterProxy>(std::move(writer));
+}
+
+void RecordBatchFileWriter::writeRecordBatch(
+    libmexclass::proxy::method::Context& context) {
+  namespace mda = ::matlab::data;
+  using RecordBatchProxy = ::arrow::matlab::tabular::proxy::RecordBatch;
+
+  mda::StructArray opts = context.inputs[0];
+  const mda::TypedArray<uint64_t> record_batch_proxy_id_mda =
+      opts[0]["RecordBatchProxyID"];
+  const uint64_t record_batch_proxy_id = record_batch_proxy_id_mda[0];
+
+  auto proxy = 
libmexclass::proxy::ProxyManager::getProxy(record_batch_proxy_id);
+  auto record_batch_proxy = std::static_pointer_cast<RecordBatchProxy>(proxy);
+  auto record_batch = record_batch_proxy->unwrap();
+
+  MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(writer->WriteRecordBatch(*record_batch), 
context,
+                                      error::IPC_RECORD_BATCH_WRITE_FAILED);
+}
+
+void RecordBatchFileWriter::writeTable(libmexclass::proxy::method::Context& 
context) {
+  namespace mda = ::matlab::data;
+  using TableProxy = ::arrow::matlab::tabular::proxy::Table;
+
+  mda::StructArray opts = context.inputs[0];
+  const mda::TypedArray<uint64_t> table_proxy_id_mda = opts[0]["TableProxyID"];
+  const uint64_t table_proxy_id = table_proxy_id_mda[0];
+
+  auto proxy = libmexclass::proxy::ProxyManager::getProxy(table_proxy_id);
+  auto table_proxy = std::static_pointer_cast<TableProxy>(proxy);
+  auto table = table_proxy->unwrap();
+
+  MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(writer->WriteTable(*table), context,
+                                      error::IPC_RECORD_BATCH_WRITE_FAILED);
+}
+
+void RecordBatchFileWriter::close(libmexclass::proxy::method::Context& 
context) {
+  MATLAB_ERROR_IF_NOT_OK_WITH_CONTEXT(writer->Close(), context,
+                                      
error::IPC_RECORD_BATCH_WRITE_CLOSE_FAILED);
+}
+
+}  // namespace arrow::matlab::io::ipc::proxy
\ No newline at end of file
diff --git 
a/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_writer.h 
b/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_writer.h
new file mode 100644
index 0000000000..bfd83504f1
--- /dev/null
+++ b/matlab/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_writer.h
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "arrow/ipc/writer.h"
+#include "libmexclass/proxy/Proxy.h"
+
+namespace arrow::matlab::io::ipc::proxy {
+
+class RecordBatchFileWriter : public libmexclass::proxy::Proxy {
+ public:
+  RecordBatchFileWriter(std::shared_ptr<arrow::ipc::RecordBatchWriter> writer);
+
+  ~RecordBatchFileWriter() = default;
+
+  static libmexclass::proxy::MakeResult make(
+      const libmexclass::proxy::FunctionArguments& constructor_arguments);
+
+ protected:
+  std::shared_ptr<arrow::ipc::RecordBatchWriter> writer;
+
+  void writeRecordBatch(libmexclass::proxy::method::Context& context);
+
+  void writeTable(libmexclass::proxy::method::Context& context);
+
+  void close(libmexclass::proxy::method::Context& context);
+};
+
+}  // namespace arrow::matlab::io::ipc::proxy
\ No newline at end of file
diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.cc 
b/matlab/src/cpp/arrow/matlab/proxy/factory.cc
index 53a19da82e..8326b43719 100644
--- a/matlab/src/cpp/arrow/matlab/proxy/factory.cc
+++ b/matlab/src/cpp/arrow/matlab/proxy/factory.cc
@@ -34,6 +34,8 @@
 #include "arrow/matlab/io/csv/proxy/table_writer.h"
 #include "arrow/matlab/io/feather/proxy/reader.h"
 #include "arrow/matlab/io/feather/proxy/writer.h"
+#include "arrow/matlab/io/ipc/proxy/record_batch_file_reader.h"
+#include "arrow/matlab/io/ipc/proxy/record_batch_file_writer.h"
 #include "arrow/matlab/tabular/proxy/record_batch.h"
 #include "arrow/matlab/tabular/proxy/schema.h"
 #include "arrow/matlab/tabular/proxy/table.h"
@@ -107,6 +109,8 @@ libmexclass::proxy::MakeResult Factory::make_proxy(
   REGISTER_PROXY(arrow.c.proxy.ArrayImporter       , 
arrow::matlab::c::proxy::ArrayImporter);
   REGISTER_PROXY(arrow.c.proxy.Schema              , 
arrow::matlab::c::proxy::Schema);
   REGISTER_PROXY(arrow.c.proxy.RecordBatchImporter , 
arrow::matlab::c::proxy::RecordBatchImporter);
+  REGISTER_PROXY(arrow.io.ipc.proxy.RecordBatchFileReader , 
arrow::matlab::io::ipc::proxy::RecordBatchFileReader);
+  REGISTER_PROXY(arrow.io.ipc.proxy.RecordBatchFileWriter , 
arrow::matlab::io::ipc::proxy::RecordBatchFileWriter);
   // clang-format on
 
   return libmexclass::error::Error{error::UNKNOWN_PROXY_ERROR_ID,
diff --git a/matlab/src/matlab/+arrow/+io/+ipc/RecordBatchFileReader.m 
b/matlab/src/matlab/+arrow/+io/+ipc/RecordBatchFileReader.m
new file mode 100644
index 0000000000..fc15863603
--- /dev/null
+++ b/matlab/src/matlab/+arrow/+io/+ipc/RecordBatchFileReader.m
@@ -0,0 +1,64 @@
+%RECORDBATCHFILEREADER Class for reading Arrow RecordBatches from the 
+% Arrow binary (IPC) format.
+
+% Licensed to the Apache Software Foundation (ASF) under one or more
+% contributor license agreements.  See the NOTICE file distributed with
+% this work for additional information regarding copyright ownership.
+% The ASF licenses this file to you under the Apache License, Version
+% 2.0 (the "License"); you may not use this file except in compliance
+% with the License.  You may obtain a copy of the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+% implied.  See the License for the specific language governing
+% permissions and limitations under the License.
+
+classdef RecordBatchFileReader < matlab.mixin.Scalar
+
+    properties(SetAccess=private, GetAccess=public, Hidden)
+        Proxy
+    end
+
+    properties (Dependent, SetAccess=private, GetAccess=public)
+        NumRecordBatches
+        Schema
+    end
+
+    methods
+        function obj = RecordBatchFileReader(filename)
+            arguments
+                filename(1, 1) string {mustBeNonzeroLengthText} 
+            end
+            args = struct(Filename=filename);
+            proxyName = "arrow.io.ipc.proxy.RecordBatchFileReader";
+            obj.Proxy = arrow.internal.proxy.create(proxyName, args);
+        end
+
+        function numRecordBatches = get.NumRecordBatches(obj)
+            numRecordBatches = obj.Proxy.getNumRecordBatches();
+        end
+
+        function schema = get.Schema(obj)
+            proxyID = obj.Proxy.getSchema();
+            proxyName = "arrow.tabular.proxy.Schema";
+            proxy = libmexclass.proxy.Proxy(ID=proxyID, Name=proxyName);
+            schema = arrow.tabular.Schema(proxy);
+        end
+
+        function rb = read(obj, index)
+            arguments
+                obj(1, 1) arrow.io.ipc.RecordBatchFileReader
+                index(1, 1)
+            end
+            index = arrow.internal.validate.index.numeric(index, "int32");
+            args = struct(Index=index);
+            proxyID = obj.Proxy.readRecordBatchAtIndex(args);
+            proxyName = "arrow.tabular.proxy.RecordBatch";
+            proxy = libmexclass.proxy.Proxy(ID=proxyID, Name=proxyName);
+            rb = arrow.tabular.RecordBatch(proxy);
+        end
+    end
+end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+io/+ipc/RecordBatchFileWriter.m 
b/matlab/src/matlab/+arrow/+io/+ipc/RecordBatchFileWriter.m
new file mode 100644
index 0000000000..aee4acf5c1
--- /dev/null
+++ b/matlab/src/matlab/+arrow/+io/+ipc/RecordBatchFileWriter.m
@@ -0,0 +1,77 @@
+%RECORDBATCHFILEWRITER Class for serializing record batches to a file using
+% the IPC format.
+
+% Licensed to the Apache Software Foundation (ASF) under one or more
+% contributor license agreements.  See the NOTICE file distributed with
+% this work for additional information regarding copyright ownership.
+% The ASF licenses this file to you under the Apache License, Version
+% 2.0 (the "License"); you may not use this file except in compliance
+% with the License.  You may obtain a copy of the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+% implied.  See the License for the specific language governing
+% permissions and limitations under the License.
+
+classdef RecordBatchFileWriter < matlab.mixin.Scalar
+
+    properties(SetAccess=private, GetAccess=public, Hidden)
+        Proxy
+    end
+
+    methods
+        function obj = RecordBatchFileWriter(filename, schema)
+            arguments
+                filename(1, 1) string {mustBeNonzeroLengthText} 
+                schema(1, 1) arrow.tabular.Schema
+            end
+            args = struct(Filename=filename, SchemaProxyID=schema.Proxy.ID);
+            proxyName = "arrow.io.ipc.proxy.RecordBatchFileWriter";
+            obj.Proxy = arrow.internal.proxy.create(proxyName, args);
+        end
+
+        function writeRecordBatch(obj, recordBatch)
+            arguments
+                obj(1, 1) arrow.io.ipc.RecordBatchFileWriter
+                recordBatch(1, 1) arrow.tabular.RecordBatch
+            end
+
+            args = struct(RecordBatchProxyID=recordBatch.Proxy.ID);
+            obj.Proxy.writeRecordBatch(args);
+        end
+
+        function writeTable(obj, arrowTable)
+            arguments
+                obj(1, 1) arrow.io.ipc.RecordBatchFileWriter
+                arrowTable(1, 1) arrow.tabular.Table
+            end
+
+            args = struct(TableProxyID=arrowTable.Proxy.ID);
+            obj.Proxy.writeTable(args);
+        end
+
+        function write(obj, tabularObj)
+            arguments
+                obj(1, 1) arrow.io.ipc.RecordBatchFileWriter
+                tabularObj(1, 1)
+            end
+            if isa(tabularObj, "arrow.tabular.RecordBatch")
+                obj.writeRecordBatch(tabularObj);
+            elseif isa(tabularObj, "arrow.tabular.Table")
+                obj.writeTable(tabularObj);
+            else
+                id = "arrow:matlab:ipc:write:InvalidType";
+                msg = "tabularObj input argument must be an instance of " + ...
+                    "either arrow.tabular.RecordBatch or arrow.tabular.Table.";
+                error(id, msg);
+            end
+        end
+
+        function close(obj)
+            obj.Proxy.close();
+        end
+    end
+end
diff --git a/matlab/test/arrow/io/ipc/tRecordBatchFileReader.m 
b/matlab/test/arrow/io/ipc/tRecordBatchFileReader.m
new file mode 100644
index 0000000000..eb0069d307
--- /dev/null
+++ b/matlab/test/arrow/io/ipc/tRecordBatchFileReader.m
@@ -0,0 +1,184 @@
+%TRECORDBATCHFILEREADER Unit tests for arrow.io.ipc.RecordBatchFileReader.
+
+% Licensed to the Apache Software Foundation (ASF) under one or more
+% contributor license agreements.  See the NOTICE file distributed with
+% this work for additional information regarding copyright ownership.
+% The ASF licenses this file to you under the Apache License, Version
+% 2.0 (the "License"); you may not use this file except in compliance
+% with the License.  You may obtain a copy of the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+% implied.  See the License for the specific language governing
+% permissions and limitations under the License.
+classdef tRecordBatchFileReader < matlab.unittest.TestCase
+
+    properties
+        DataFolder
+        ZeroBatchFile
+        OneBatchFile
+        MultipleBatchFile
+    end
+
+    methods(TestClassSetup)
+        function setupDataFolder(testCase)
+            import matlab.unittest.fixtures.TemporaryFolderFixture
+            fixture = testCase.applyFixture(TemporaryFolderFixture);
+            testCase.DataFolder = string(fixture.Folder);
+        end
+
+        function setupZeroBatchFile(testCase)
+            fieldA = arrow.field("A", arrow.string());
+            fieldB = arrow.field("B", arrow.float32());
+            schema = arrow.schema([fieldA, fieldB]);
+            fname = fullfile(testCase.DataFolder, "ZeroBatchFile.arrow");
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            writer.close();
+            testCase.ZeroBatchFile = fname;
+        end
+
+        function setupOneBatchFile(testCase)
+            t = table(["Row1"; "Row2"], single([1; 2]), VariableNames=["A", 
"B"]);
+            recordBatch = arrow.recordBatch(t);
+            fname = fullfile(testCase.DataFolder, "OneBatchFile.arrow");
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, 
recordBatch.Schema);
+            writer.writeRecordBatch(recordBatch);
+            writer.close();
+            testCase.OneBatchFile = fname;
+        end
+
+        function setupMultipleBatchFile(testCase)
+            t1 = table(["Row1"; "Row2"], single([1; 2]), VariableNames=["A", 
"B"]);
+            t2 = table(["Row3"; "Row4"], single([3; 4]), VariableNames=["A", 
"B"]);
+            recordBatch1 = arrow.recordBatch(t1);
+            recordBatch2 = arrow.recordBatch(t2);
+            fname = fullfile(testCase.DataFolder, "MultipleBatchFile.arrow");
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, 
recordBatch1.Schema);
+            writer.writeRecordBatch(recordBatch1);
+            writer.writeRecordBatch(recordBatch2);
+            writer.close();
+            testCase.MultipleBatchFile = fname;
+        end
+    end
+
+    methods (Test)
+        function ZeroLengthFilenameError(testCase)
+            % Verify RecordBatchFileReader throws an exception with the
+            % identifier MATLAB:validators:mustBeNonzeroLengthText if the
+            % filename input argument given is a zero length string.
+            fcn = @() arrow.io.ipc.RecordBatchFileReader("");
+            testCase.verifyError(fcn, 
"MATLAB:validators:mustBeNonzeroLengthText");
+        end
+
+        function MissingStringFilenameError(testCase)
+            % Verify RecordBatchFileReader throws an exception with the
+            % identifier MATLAB:validators:mustBeNonzeroLengthText if the
+            % filename input argument given is a missing string.
+            fcn = @() arrow.io.ipc.RecordBatchFileReader(string(missing));
+            testCase.verifyError(fcn, 
"MATLAB:validators:mustBeNonzeroLengthText");
+        end
+
+        function FilenameInvalidTypeError(testCase)
+            % Verify RecordBatchFileReader throws an exception with the
+            % identifier MATLAB:validators:UnableToConvert if the filename
+            % input argument is neither a scalar string nor a char vector.
+            fcn = @() arrow.io.ipc.RecordBatchFileReader(table);
+            testCase.verifyError(fcn, "MATLAB:validation:UnableToConvert");
+        end
+
+        function NumRecordBatches(testCase)
+            % Verify the getter method for NumRecordBatches returns the
+            % expected value.
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.ZeroBatchFile);
+            testCase.verifyEqual(reader.NumRecordBatches, int32(0));
+
+            reader = arrow.io.ipc.RecordBatchFileReader(testCase.OneBatchFile);
+            testCase.verifyEqual(reader.NumRecordBatches, int32(1));
+
+             reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.MultipleBatchFile);
+            testCase.verifyEqual(reader.NumRecordBatches, int32(2));
+        end
+
+        function NumRecordNoSetter(testCase)
+            % Verify the NumRecordBatches property is not settable.
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.ZeroBatchFile);
+            testCase.verifyError(@() setfield(reader, "NumRecordBatches", 
int32(10)), "MATLAB:class:SetProhibited");
+        end
+
+        function Schema(testCase)
+            % Verify the getter method for Schema returns the
+            % expected value.
+            fieldA = arrow.field("A", arrow.string());
+            fieldB = arrow.field("B", arrow.float32());
+            expectedSchema = arrow.schema([fieldA fieldB]);
+            
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.ZeroBatchFile);
+            testCase.verifyEqual(reader.Schema, expectedSchema);
+
+            reader = arrow.io.ipc.RecordBatchFileReader(testCase.OneBatchFile);
+            testCase.verifyEqual(reader.Schema, expectedSchema);
+
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.MultipleBatchFile);
+            testCase.verifyEqual(reader.Schema, expectedSchema);
+        end
+
+        function SchemaNoSetter(testCase)
+            % Verify the Schema property is not settable.
+            fieldC = arrow.field("C", arrow.date32());
+            schema = arrow.schema(fieldC);
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.ZeroBatchFile);
+            testCase.verifyError(@() setfield(reader, "Schema", schema), 
"MATLAB:class:SetProhibited");
+        end
+
+        function readInvalidIndexType(testCase)
+            % Verify read throws an exception with the identifier
+            % arrow:badsubscript:NonNumeric if the index argument given is
+            % not numeric.
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.MultipleBatchFile);
+
+            fcn = @() reader.read("index");
+            testCase.verifyError(fcn, "arrow:badsubscript:NonNumeric");
+        end
+
+        function readInvalidNumericIndex(testCase)
+            % Verify read throws an exception if the index argument given
+            % is nonpositive or noninteger number.
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.MultipleBatchFile);
+            fcn = @() reader.read(-1);
+            testCase.verifyError(fcn, "arrow:badsubscript:NonPositive");
+            fcn = @() reader.read(0);
+            testCase.verifyError(fcn, "arrow:badsubscript:NonPositive");
+            fcn = @() reader.read(1.1);
+            testCase.verifyError(fcn, "arrow:badsubscript:NonInteger");
+        end
+
+        function readInvalidNumericIndexValue(testCase)
+            % Verify read throws an exception with the identifier 
+            % arrow:io:ipc:InvalidIndex if the index given is greater
+            % than the NumRecordBatches in the file.
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.MultipleBatchFile);
+            fcn = @() reader.read(3);
+            testCase.verifyError(fcn, "arrow:io:ipc:InvalidIndex");
+        end
+
+        function readAtIndex(testCase)
+            % Verify read returns the expected RecordBatch for the given
+            % index.
+            t1 = table(["Row1"; "Row2"], single([1; 2]), VariableNames=["A", 
"B"]);
+            t2 = table(["Row3"; "Row4"], single([3; 4]), VariableNames=["A", 
"B"]);
+
+            reader = 
arrow.io.ipc.RecordBatchFileReader(testCase.MultipleBatchFile);
+            
+            actual1 = reader.read(1);
+            expected1 = arrow.recordBatch(t1);
+            testCase.verifyEqual(actual1, expected1);
+
+            actual2 = reader.read(2);
+            expected2 = arrow.recordBatch(t2);
+            testCase.verifyEqual(actual2, expected2);
+        end
+    end
+end
\ No newline at end of file
diff --git a/matlab/test/arrow/io/ipc/tRecordBatchFileWriter.m 
b/matlab/test/arrow/io/ipc/tRecordBatchFileWriter.m
new file mode 100644
index 0000000000..25bbf4474e
--- /dev/null
+++ b/matlab/test/arrow/io/ipc/tRecordBatchFileWriter.m
@@ -0,0 +1,211 @@
+%TRECORDBATCHFILEWRITER Unit tests for arrow.io.ipc.RecordBatchFileWriter.
+
+% Licensed to the Apache Software Foundation (ASF) under one or more
+% contributor license agreements.  See the NOTICE file distributed with
+% this work for additional information regarding copyright ownership.
+% The ASF licenses this file to you under the Apache License, Version
+% 2.0 (the "License"); you may not use this file except in compliance
+% with the License.  You may obtain a copy of the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+% implied.  See the License for the specific language governing
+% permissions and limitations under the License.
+
+classdef tRecordBatchFileWriter < matlab.unittest.TestCase
+
+    methods
+        function folder = setupTemporaryFolder(testCase)
+            import matlab.unittest.fixtures.TemporaryFolderFixture
+            fixture = testCase.applyFixture(TemporaryFolderFixture);
+            folder = string(fixture.Folder);
+        end
+    end
+
+    methods (Test)
+        function ZeroLengthFilenameError(testCase)
+            % Verify RecordBatchFileWriter throws an exception with the
+            % identifier MATLAB:validators:mustBeNonzeroLengthText if the
+            % filename input argument given is a zero length string.
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            fcn = @() arrow.io.ipc.RecordBatchFileWriter("", schema);
+            testCase.verifyError(fcn, 
"MATLAB:validators:mustBeNonzeroLengthText");
+        end
+
+        function MissingStringFilenameError(testCase)
+            % Verify RecordBatchFileWriter throws an exception with the
+            % identifier MATLAB:validators:mustBeNonzeroLengthText if the
+            % filename input argument given is  a missing string.
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            fcn = @() arrow.io.ipc.RecordBatchFileWriter(string(missing), 
schema);
+            testCase.verifyError(fcn, 
"MATLAB:validators:mustBeNonzeroLengthText");
+        end
+
+        function FilenameInvalidTypeError(testCase)
+            % Verify RecordBatchFileWriter throws an exception with the
+            % identifier MATLAB:validators:UnableToConvert if the filename
+            % input argument is neither a scalar string nor a char vector.
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            fcn = @() arrow.io.ipc.RecordBatchFileWriter(table, schema);
+            testCase.verifyError(fcn, "MATLAB:validation:UnableToConvert");
+        end
+
+        function InvalidSchemaType(testCase)
+            % Verify RecordBatchFileWriter throws an exception with the
+            % identifier MATLAB:validators:UnableToConvert if the schema
+            % input argument is not an arrow.tabular.Schema instance.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.field("A", arrow.float64());
+            fcn = @() arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            testCase.verifyError(fcn, "MATLAB:validation:UnableToConvert");
+        end
+
+        function writeRecordBatchInvalidType(testCase)
+            % Verify writeRecordBatch throws an exception with the
+            % identifier MATLAB:validators:UnableToConvert if the
+            % recordBatch input argument given is not an
+            % arrow.tabular.RecordBatch instance.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            arrowTable = arrow.table(table([1 2 3 4]', VariableNames="A"));
+            fcn = @() writer.writeRecordBatch(arrowTable);
+            testCase.verifyError(fcn, "MATLAB:validation:UnableToConvert");
+        end
+
+        function writeTableInvalidType(testCase)
+            % Verify writeTable throws an exception with the
+            % identifier MATLAB:validators:UnableToConvert if the table 
+            % input argument given is not an arrow.tabular.Table instance.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            arrowRecordBatch = arrow.recordBatch(table([1 2 3 4]', 
VariableNames="A"));
+            fcn = @() writer.writeTable(arrowRecordBatch);
+            testCase.verifyError(fcn, "MATLAB:validation:UnableToConvert");
+        end
+
+        function writeInvalidType(testCase)
+            % Verify writeTable throws an exception with the
+            % identifier arrow:matlab:ipc:write:InvalidType if the 
+            % tabularObj input argument given is neither an
+            % arrow.tabular.Table or an arrow.tabular.RecordBatch.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            fcn = @() writer.write(schema);
+            testCase.verifyError(fcn, "arrow:matlab:ipc:write:InvalidType");
+        end
+
+        function writeRecordBatchInvalidSchema(testCase)
+            % Verify writeRecordBatch throws an exception with the
+            % identifier arrow:io:ipc:FailedToWriteRecordBatch if the
+            % schema of the given record batch does match the expected 
+            % schema.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+
+            arrowRecordBatch = arrow.recordBatch(table([1 2 3 4]', 
VariableNames="B"));
+            fcn = @() writer.writeRecordBatch(arrowRecordBatch);
+            testCase.verifyError(fcn, "arrow:io:ipc:FailedToWriteRecordBatch");
+        end
+
+         function writeTableInvalidSchema(testCase)
+            % Verify writeTable throws an exception with the
+            % identifier arrow:io:ipc:FailedToWriteRecordBatch if the
+            % schema of the given table does match the expected schema.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+
+            arrowTable = arrow.table(table([1 2 3 4]', VariableNames="B"));
+            fcn = @() writer.writeTable(arrowTable);
+            testCase.verifyError(fcn, "arrow:io:ipc:FailedToWriteRecordBatch");
+         end
+
+         function writeInvalidSchema(testCase)
+            % Verify write throws an exception with the
+            % identifier arrow:io:ipc:FailedToWriteRecordBatch if the
+            % schema of the given record batch or table does match the 
+            % expected schema.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+
+            arrowTable = arrow.table(table([1 2 3 4]', VariableNames="B"));
+            fcn = @() writer.write(arrowTable);
+            testCase.verifyError(fcn, "arrow:io:ipc:FailedToWriteRecordBatch");
+
+            arrowRecordBatch = arrow.recordBatch(table([1 2 3 4]', 
VariableNames="B"));
+            fcn = @() writer.write(arrowRecordBatch);
+            testCase.verifyError(fcn, "arrow:io:ipc:FailedToWriteRecordBatch");
+         end
+
+         function writeRecordBatchSmoke(testCase)
+            % Verify writeRecordBatch does not error or issue a warning
+            % if it successfully writes the record batch to the file.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            arrowRecordBatch = arrow.recordBatch(table([1 2 3 4]', 
VariableNames="A"));
+
+            fcn = @() writer.writeRecordBatch(arrowRecordBatch);
+            testCase.verifyWarningFree(fcn);
+         end
+
+        function writeTableBatchSmoke(testCase)
+            % Verify writeTable does not error or issue a warning
+            % if it successfully writes the table to the file.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            arrowTable = arrow.table(table([1 2 3 4]', VariableNames="A"));
+
+            fcn = @() writer.writeTable(arrowTable);
+            testCase.verifyWarningFree(fcn);
+        end
+
+        function writeSmoke(testCase)
+            % Verify write does not error or issue a warning if it
+            % successfully writes the record batch or table to the file.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            arrowRecordBatch = arrow.recordBatch(table([1 2 3 4]', 
VariableNames="A"));
+
+            fcn = @() writer.write(arrowRecordBatch);
+            testCase.verifyWarningFree(fcn);
+
+            arrowTable = arrow.table(table([1 2 3 4]', VariableNames="A"));
+            fcn = @() writer.write(arrowTable);
+            testCase.verifyWarningFree(fcn);
+        end
+
+        function closeSmoke(testCase)
+            % Verify close does not error or issue a warning if it was
+            % successful.
+            folder = testCase.setupTemporaryFolder();
+            fname = fullfile(folder, "data.arrow");
+            schema = arrow.schema(arrow.field("A", arrow.float64()));
+            writer = arrow.io.ipc.RecordBatchFileWriter(fname, schema);
+            arrowTable = arrow.table(table([1 2 3 4]', VariableNames="A"));
+            writer.write(arrowTable);
+            fcn = @() writer.close();
+            testCase.verifyWarningFree(fcn);
+        end
+    end
+end
\ No newline at end of file
diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake 
b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
index 0a747e648c..5ed68ec246 100644
--- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
+++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
@@ -79,7 +79,9 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES 
"${CMAKE_SOURCE_DIR}/src/cpp/a
                                                   
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/c/proxy/array.cc"
                                                   
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/c/proxy/array_importer.cc"
                                                   
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/c/proxy/schema.cc"
-                                                  
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/c/proxy/record_batch_importer.cc")
+                                                  
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/c/proxy/record_batch_importer.cc"
+                                                  
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_reader.cc"
+                                                  
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/io/ipc/proxy/record_batch_file_writer.cc")
 
 
 set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_INCLUDE_DIR 
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy")


Reply via email to