@@ -982,6 +982,14 @@ impl<W: Write> FileWriter<W> {
982
982
self . writer . get_mut ( )
983
983
}
984
984
985
+ /// Flush the underlying writer.
986
+ ///
987
+ /// Both the BufWriter and the underlying writer are flushed.
988
+ pub fn flush ( & mut self ) -> Result < ( ) , ArrowError > {
989
+ self . writer . flush ( ) ?;
990
+ Ok ( ( ) )
991
+ }
992
+
985
993
/// Unwraps the BufWriter housed in FileWriter.writer, returning the underlying
986
994
/// writer
987
995
///
@@ -1097,6 +1105,14 @@ impl<W: Write> StreamWriter<W> {
1097
1105
self . writer . get_mut ( )
1098
1106
}
1099
1107
1108
+ /// Flush the underlying writer.
1109
+ ///
1110
+ /// Both the BufWriter and the underlying writer are flushed.
1111
+ pub fn flush ( & mut self ) -> Result < ( ) , ArrowError > {
1112
+ self . writer . flush ( ) ?;
1113
+ Ok ( ( ) )
1114
+ }
1115
+
1100
1116
/// Unwraps the BufWriter housed in StreamWriter.writer, returning the underlying
1101
1117
/// writer
1102
1118
///
@@ -2615,4 +2631,51 @@ mod tests {
2615
2631
offset from expected alignment of 16 by 8"
2616
2632
) ;
2617
2633
}
2634
+
2635
+ #[ test]
2636
+ fn test_flush ( ) {
2637
+ // We write a schema which is small enough to fit into a buffer and not get flushed,
2638
+ // and then force the write with .flush().
2639
+ let num_cols = 2 ;
2640
+ let mut fields = Vec :: new ( ) ;
2641
+ let options = IpcWriteOptions :: try_new ( 8 , false , MetadataVersion :: V5 ) . unwrap ( ) ;
2642
+ for i in 0 ..num_cols {
2643
+ let field = Field :: new ( & format ! ( "col_{}" , i) , DataType :: Decimal128 ( 38 , 10 ) , true ) ;
2644
+ fields. push ( field) ;
2645
+ }
2646
+ let schema = Schema :: new ( fields) ;
2647
+ let inner_stream_writer = BufWriter :: with_capacity ( 1024 , Vec :: new ( ) ) ;
2648
+ let inner_file_writer = BufWriter :: with_capacity ( 1024 , Vec :: new ( ) ) ;
2649
+ let mut stream_writer =
2650
+ StreamWriter :: try_new_with_options ( inner_stream_writer, & schema, options. clone ( ) )
2651
+ . unwrap ( ) ;
2652
+ let mut file_writer =
2653
+ FileWriter :: try_new_with_options ( inner_file_writer, & schema, options) . unwrap ( ) ;
2654
+
2655
+ let stream_bytes_written_on_new = stream_writer. get_ref ( ) . get_ref ( ) . len ( ) ;
2656
+ let file_bytes_written_on_new = file_writer. get_ref ( ) . get_ref ( ) . len ( ) ;
2657
+ stream_writer. flush ( ) . unwrap ( ) ;
2658
+ file_writer. flush ( ) . unwrap ( ) ;
2659
+ let stream_bytes_written_on_flush = stream_writer. get_ref ( ) . get_ref ( ) . len ( ) ;
2660
+ let file_bytes_written_on_flush = file_writer. get_ref ( ) . get_ref ( ) . len ( ) ;
2661
+ let stream_out = stream_writer. into_inner ( ) . unwrap ( ) . into_inner ( ) . unwrap ( ) ;
2662
+ // Finishing a stream writes the continuation bytes in MetadataVersion::V5 (4 bytes)
2663
+ // and then a length of 0 (4 bytes) for a total of 8 bytes.
2664
+ // Everything before that should have been flushed in the .flush() call.
2665
+ let expected_stream_flushed_bytes = stream_out. len ( ) - 8 ;
2666
+ // A file write is the same as the stream write except for the leading magic string
2667
+ // ARROW1 plus padding, which is 8 bytes.
2668
+ let expected_file_flushed_bytes = expected_stream_flushed_bytes + 8 ;
2669
+
2670
+ assert ! (
2671
+ stream_bytes_written_on_new < stream_bytes_written_on_flush,
2672
+ "this test makes no sense if flush is not actually required"
2673
+ ) ;
2674
+ assert ! (
2675
+ file_bytes_written_on_new < file_bytes_written_on_flush,
2676
+ "this test makes no sense if flush is not actually required"
2677
+ ) ;
2678
+ assert_eq ! ( stream_bytes_written_on_flush, expected_stream_flushed_bytes) ;
2679
+ assert_eq ! ( file_bytes_written_on_flush, expected_file_flushed_bytes) ;
2680
+ }
2618
2681
}
0 commit comments