0
# Binary I/O Operations
1
2
The BSON I/O system provides high-performance binary reading and writing capabilities for BSON data. It includes abstract reader/writer interfaces, concrete implementations for different data sources, and buffering support for optimal performance.
3
4
## BsonReader Interface
5
6
The `BsonReader` interface provides the core interface for reading BSON data.
7
8
```java { .api }
9
public interface BsonReader extends Closeable {
10
/**
11
* Reads a BSON type from the reader.
12
* @return the BSON type
13
*/
14
BsonType readBsonType();
15
16
/**
17
* Reads the name of an element from the reader.
18
* @return the element name
19
*/
20
String readName();
21
22
/**
23
* Reads a BSON Binary value from the reader.
24
* @return the Binary value
25
*/
26
BsonBinary readBinaryData();
27
28
/**
29
* Reads a BSON Boolean value from the reader.
30
* @return the Boolean value
31
*/
32
boolean readBoolean();
33
34
/**
35
* Reads a BSON DateTime value from the reader.
36
* @return the DateTime value as milliseconds since epoch
37
*/
38
long readDateTime();
39
40
/**
41
* Reads a BSON Double value from the reader.
42
* @return the Double value
43
*/
44
double readDouble();
45
46
/**
47
* Reads a BSON Int32 value from the reader.
48
* @return the Int32 value
49
*/
50
int readInt32();
51
52
/**
53
* Reads a BSON Int64 value from the reader.
54
* @return the Int64 value
55
*/
56
long readInt64();
57
58
/**
59
* Reads a BSON Decimal128 value from the reader.
60
* @return the Decimal128 value
61
*/
62
Decimal128 readDecimal128();
63
64
/**
65
* Reads a BSON JavaScript value from the reader.
66
* @return the JavaScript code
67
*/
68
String readJavaScript();
69
70
/**
71
* Reads a BSON JavaScript with Scope value from the reader.
72
* @return the JavaScript code
73
*/
74
String readJavaScriptWithScope();
75
76
/**
77
* Reads a BSON MaxKey value from the reader.
78
*/
79
void readMaxKey();
80
81
/**
82
* Reads a BSON MinKey value from the reader.
83
*/
84
void readMinKey();
85
86
/**
87
* Reads a BSON null value from the reader.
88
*/
89
void readNull();
90
91
/**
92
* Reads a BSON ObjectId value from the reader.
93
* @return the ObjectId value
94
*/
95
ObjectId readObjectId();
96
97
/**
98
* Reads a BSON regular expression value from the reader.
99
* @return the regular expression
100
*/
101
BsonRegularExpression readRegularExpression();
102
103
/**
104
* Reads a BSON string value from the reader.
105
* @return the string value
106
*/
107
String readString();
108
109
/**
110
* Reads a BSON symbol value from the reader.
111
* @return the symbol value
112
*/
113
String readSymbol();
114
115
/**
116
* Reads a BSON timestamp value from the reader.
117
* @return the timestamp
118
*/
119
BsonTimestamp readTimestamp();
120
121
/**
122
* Reads a BSON undefined value from the reader.
123
*/
124
void readUndefined();
125
126
/**
127
* Reads the start of a BSON array.
128
*/
129
void readStartArray();
130
131
/**
132
* Reads the end of a BSON array.
133
*/
134
void readEndArray();
135
136
/**
137
* Reads the start of a BSON document.
138
*/
139
void readStartDocument();
140
141
/**
142
* Reads the end of a BSON document.
143
*/
144
void readEndDocument();
145
146
/**
147
* Returns a mark for the current position.
148
* @return the mark
149
*/
150
BsonReaderMark getMark();
151
152
/**
153
* Resets the reader to the marked position.
154
* @param mark the mark to reset to
155
*/
156
void reset(BsonReaderMark mark);
157
158
/**
159
* Gets the current context type.
160
* @return the current context type
161
*/
162
public BsonContextType getCurrentBsonType();
163
164
/**
165
* Gets the current name.
166
* @return the current name
167
*/
168
public String getCurrentName();
169
170
/**
171
* Gets the reader state.
172
* @return the reader state
173
*/
174
public AbstractBsonReader.State getState();
175
176
/**
177
* Skips the name (reader must be positioned on a name).
178
*/
179
void skipName();
180
181
/**
182
* Skips the value (reader must be positioned on a value).
183
*/
184
void skipValue();
185
186
void close();
187
}
188
```
189
190
## BsonWriter Interface
191
192
The abstract `BsonWriter` class provides the core interface for writing BSON data.
193
194
```java { .api }
195
class BsonWriter implements Closeable, Flushable {
196
/**
197
* Writes a BSON Binary value to the writer.
198
* @param binary the Binary value
199
*/
200
void writeBinaryData(BsonBinary binary);
201
202
/**
203
* Writes a BSON Binary value to the writer.
204
* @param name the field name
205
* @param binary the Binary value
206
*/
207
public void writeBinaryData(String name, BsonBinary binary);
208
209
/**
210
* Writes a BSON Boolean value to the writer.
211
* @param value the Boolean value
212
*/
213
void writeBoolean(boolean value);
214
215
/**
216
* Writes a BSON Boolean value to the writer.
217
* @param name the field name
218
* @param value the Boolean value
219
*/
220
public void writeBoolean(String name, boolean value);
221
222
/**
223
* Writes a BSON DateTime value to the writer.
224
* @param value the DateTime value as milliseconds since epoch
225
*/
226
void writeDateTime(long value);
227
228
/**
229
* Writes a BSON DateTime value to the writer.
230
* @param name the field name
231
* @param value the DateTime value as milliseconds since epoch
232
*/
233
public void writeDateTime(String name, long value);
234
235
/**
236
* Writes a BSON Double value to the writer.
237
* @param value the Double value
238
*/
239
void writeDouble(double value);
240
241
/**
242
* Writes a BSON Double value to the writer.
243
* @param name the field name
244
* @param value the Double value
245
*/
246
public void writeDouble(String name, double value);
247
248
/**
249
* Writes a BSON Int32 value to the writer.
250
* @param value the Int32 value
251
*/
252
void writeInt32(int value);
253
254
/**
255
* Writes a BSON Int32 value to the writer.
256
* @param name the field name
257
* @param value the Int32 value
258
*/
259
public void writeInt32(String name, int value);
260
261
/**
262
* Writes a BSON Int64 value to the writer.
263
* @param value the Int64 value
264
*/
265
void writeInt64(long value);
266
267
/**
268
* Writes a BSON Int64 value to the writer.
269
* @param name the field name
270
* @param value the Int64 value
271
*/
272
public void writeInt64(String name, long value);
273
274
/**
275
* Writes a BSON Decimal128 value to the writer.
276
* @param value the Decimal128 value
277
*/
278
void writeDecimal128(Decimal128 value);
279
280
/**
281
* Writes a BSON JavaScript value to the writer.
282
* @param code the JavaScript code
283
*/
284
void writeJavaScript(String code);
285
286
/**
287
* Writes a BSON JavaScript with Scope value to the writer.
288
* @param code the JavaScript code
289
*/
290
void writeJavaScriptWithScope(String code);
291
292
/**
293
* Writes a BSON MaxKey value to the writer.
294
*/
295
void writeMaxKey();
296
297
/**
298
* Writes a BSON MinKey value to the writer.
299
*/
300
void writeMinKey();
301
302
/**
303
* Writes a field name to the writer.
304
* @param name the field name
305
*/
306
void writeName(String name);
307
308
/**
309
* Writes a BSON null value to the writer.
310
*/
311
void writeNull();
312
313
/**
314
* Writes a BSON null value to the writer.
315
* @param name the field name
316
*/
317
public void writeNull(String name);
318
319
/**
320
* Writes a BSON ObjectId value to the writer.
321
* @param objectId the ObjectId value
322
*/
323
void writeObjectId(ObjectId objectId);
324
325
/**
326
* Writes a BSON regular expression value to the writer.
327
* @param regularExpression the regular expression
328
*/
329
void writeRegularExpression(BsonRegularExpression regularExpression);
330
331
/**
332
* Writes a BSON string value to the writer.
333
* @param value the string value
334
*/
335
void writeString(String value);
336
337
/**
338
* Writes a BSON string value to the writer.
339
* @param name the field name
340
* @param value the string value
341
*/
342
public void writeString(String name, String value);
343
344
/**
345
* Writes a BSON symbol value to the writer.
346
* @param value the symbol value
347
*/
348
void writeSymbol(String value);
349
350
/**
351
* Writes a BSON timestamp value to the writer.
352
* @param value the timestamp
353
*/
354
void writeTimestamp(BsonTimestamp value);
355
356
/**
357
* Writes a BSON undefined value to the writer.
358
*/
359
void writeUndefined();
360
361
/**
362
* Writes the start of a BSON array to the writer.
363
*/
364
void writeStartArray();
365
366
/**
367
* Writes the start of a BSON array to the writer.
368
* @param name the field name
369
*/
370
public void writeStartArray(String name);
371
372
/**
373
* Writes the end of a BSON array to the writer.
374
*/
375
void writeEndArray();
376
377
/**
378
* Writes the start of a BSON document to the writer.
379
*/
380
void writeStartDocument();
381
382
/**
383
* Writes the start of a BSON document to the writer.
384
* @param name the field name
385
*/
386
public void writeStartDocument(String name);
387
388
/**
389
* Writes the end of a BSON document to the writer.
390
*/
391
void writeEndDocument();
392
393
/**
394
* Gets the writer settings.
395
* @return the writer settings
396
*/
397
public BsonWriterSettings getSettings();
398
399
/**
400
* Returns true if the writer is closed.
401
* @return true if closed
402
*/
403
public boolean isClosed();
404
405
/**
406
* Flushes any pending output to the underlying stream.
407
*/
408
void flush();
409
410
void close();
411
}
412
```
413
414
## Binary Reader Implementation
415
416
```java { .api }
417
public class BsonBinaryReader extends AbstractBsonReader {
418
/**
419
* Constructs a new instance.
420
* @param byteBuffer the input buffer, which must be positioned at the first byte of a BSON document
421
*/
422
public BsonBinaryReader(ByteBuffer byteBuffer);
423
424
/**
425
* Constructs a new instance.
426
* @param bsonInput the input stream
427
*/
428
public BsonBinaryReader(BsonInput bsonInput);
429
430
/**
431
* Gets the mark.
432
* @return the mark
433
*/
434
public BsonReaderMark getMark();
435
436
/**
437
* Resets the reader to the given mark.
438
* @param mark the mark to reset to
439
*/
440
public void reset(BsonReaderMark mark);
441
442
/**
443
* Gets the number of bytes read from the underlying stream.
444
* @return the number of bytes read
445
*/
446
public int getBytesRead();
447
448
// Implementation of abstract methods from BsonReader
449
public BsonType readBsonType();
450
public String readName();
451
public void skipName();
452
public void skipValue();
453
// ... all other BsonReader methods
454
}
455
```
456
457
## Binary Writer Implementation
458
459
```java { .api }
460
public class BsonBinaryWriter extends AbstractBsonWriter {
461
/**
462
* Constructs a new instance.
463
* @param bsonOutput the output stream
464
*/
465
public BsonBinaryWriter(BsonOutput bsonOutput);
466
467
/**
468
* Constructs a new instance.
469
* @param bsonOutput the output stream
470
* @param settings the writer settings
471
*/
472
public BsonBinaryWriter(BsonOutput bsonOutput, BsonBinaryWriterSettings settings);
473
474
/**
475
* Gets the number of bytes written to the underlying stream.
476
* @return the number of bytes written
477
*/
478
public int getBytesWritten();
479
480
// Implementation of abstract methods from BsonWriter
481
public void writeBinaryData(BsonBinary binary);
482
public void writeBoolean(boolean value);
483
public void writeDateTime(long value);
484
public void writeDouble(double value);
485
public void writeInt32(int value);
486
public void writeInt64(long value);
487
// ... all other BsonWriter methods
488
}
489
```
490
491
## Document Reader/Writer
492
493
```java { .api }
494
public class BsonDocumentReader extends AbstractBsonReader {
495
/**
496
* Constructs a new instance.
497
* @param document the document to read from
498
*/
499
public BsonDocumentReader(BsonDocument document);
500
501
// Implementation of BsonReader interface
502
public BsonType readBsonType();
503
public void readStartDocument();
504
public void readEndDocument();
505
public void readStartArray();
506
public void readEndArray();
507
// ... other methods
508
}
509
510
public class BsonDocumentWriter extends AbstractBsonWriter {
511
/**
512
* Constructs a new instance.
513
* @param document the document to write to
514
*/
515
public BsonDocumentWriter(BsonDocument document);
516
517
/**
518
* Gets the document being written to.
519
* @return the document
520
*/
521
public BsonDocument getDocument();
522
523
// Implementation of BsonWriter interface
524
public void writeBinaryData(BsonBinary binary);
525
public void writeBoolean(boolean value);
526
// ... other methods
527
}
528
```
529
530
## ByteBuf Interface
531
532
The `ByteBuf` interface provides an abstraction for binary data buffers with reference counting.
533
534
```java { .api }
535
public interface ByteBuf extends ReferenceCounted {
536
/**
537
* Gets the capacity of this buffer.
538
* @return the capacity
539
*/
540
int capacity();
541
542
/**
543
* Gets a byte at the given index.
544
* @param index the index
545
* @return the byte at the given index
546
*/
547
byte get(int index);
548
549
/**
550
* Gets bytes from the given index.
551
* @param index the index to start at
552
* @param bytes the byte array to copy into
553
* @return this
554
*/
555
ByteBuf get(int index, byte[] bytes);
556
557
/**
558
* Gets bytes from the given index.
559
* @param index the index to start at
560
* @param bytes the byte array to copy into
561
* @param offset the offset into the byte array
562
* @param length the number of bytes to copy
563
* @return this
564
*/
565
ByteBuf get(int index, byte[] bytes, int offset, int length);
566
567
/**
568
* Gets a little-endian 32-bit integer at the given index.
569
* @param index the index
570
* @return the 32-bit integer
571
*/
572
int getInt(int index);
573
574
/**
575
* Gets a little-endian 64-bit integer at the given index.
576
* @param index the index
577
* @return the 64-bit integer
578
*/
579
long getLong(int index);
580
581
/**
582
* Gets a little-endian 64-bit double at the given index.
583
* @param index the index
584
* @return the 64-bit double
585
*/
586
double getDouble(int index);
587
588
/**
589
* Puts a byte at the given index.
590
* @param index the index
591
* @param b the byte
592
* @return this
593
*/
594
ByteBuf put(int index, byte b);
595
596
/**
597
* Puts bytes at the given index.
598
* @param index the index
599
* @param src the source byte array
600
* @return this
601
*/
602
ByteBuf put(int index, byte[] src);
603
604
/**
605
* Puts a little-endian 32-bit integer at the given index.
606
* @param index the index
607
* @param value the 32-bit integer value
608
* @return this
609
*/
610
ByteBuf putInt(int index, int value);
611
612
/**
613
* Puts a little-endian 64-bit integer at the given index.
614
* @param index the index
615
* @param value the 64-bit integer value
616
* @return this
617
*/
618
ByteBuf putLong(int index, long value);
619
620
/**
621
* Puts a little-endian 64-bit double at the given index.
622
* @param index the index
623
* @param value the 64-bit double value
624
* @return this
625
*/
626
ByteBuf putDouble(int index, double value);
627
628
/**
629
* Returns a slice of this buffer.
630
* @param index the starting index of the slice
631
* @param length the length of the slice
632
* @return the sliced buffer
633
*/
634
ByteBuf slice(int index, int length);
635
636
/**
637
* Returns a duplicate of this buffer.
638
* @return the duplicated buffer
639
*/
640
ByteBuf duplicate();
641
642
/**
643
* Converts this buffer to a byte array.
644
* @return the byte array
645
*/
646
byte[] array();
647
648
/**
649
* Gets the reference count.
650
* @return the reference count
651
*/
652
int getReferenceCount();
653
654
/**
655
* Retain an additional reference to this buffer.
656
* @return this
657
*/
658
ByteBuf retain();
659
660
/**
661
* Release a reference to this buffer.
662
* @return this
663
*/
664
ByteBuf release();
665
}
666
```
667
668
## I/O Settings
669
670
```java { .api }
671
public final class BsonBinaryWriterSettings {
672
/**
673
* Gets the maximum size for a BSON document.
674
* @return the maximum document size
675
*/
676
public int getMaxDocumentSize();
677
678
/**
679
* Creates a builder for BsonBinaryWriterSettings.
680
* @return the builder
681
*/
682
public static Builder builder();
683
684
public static final class Builder {
685
/**
686
* Sets the maximum document size.
687
* @param maxDocumentSize the maximum document size
688
* @return this
689
*/
690
public Builder maxDocumentSize(int maxDocumentSize);
691
692
/**
693
* Build the settings.
694
* @return the settings
695
*/
696
public BsonBinaryWriterSettings build();
697
}
698
}
699
700
public class BsonWriterSettings {
701
/**
702
* Gets whether output should be indented.
703
* @return true if output should be indented
704
*/
705
public boolean isIndent();
706
707
/**
708
* Gets the indent characters.
709
* @return the indent characters
710
*/
711
public String getIndentCharacters();
712
713
/**
714
* Gets the new line characters.
715
* @return the new line characters
716
*/
717
public String getNewLineCharacters();
718
719
/**
720
* Creates a builder for BsonWriterSettings.
721
* @return the builder
722
*/
723
public static Builder builder();
724
725
public static final class Builder {
726
/**
727
* Sets whether the output should be indented.
728
* @param indent true if output should be indented
729
* @return this
730
*/
731
public Builder indent(boolean indent);
732
733
/**
734
* Sets the indent characters.
735
* @param indentCharacters the indent characters
736
* @return this
737
*/
738
public Builder indentCharacters(String indentCharacters);
739
740
/**
741
* Sets the new line characters.
742
* @param newLineCharacters the new line characters
743
* @return this
744
*/
745
public Builder newLineCharacters(String newLineCharacters);
746
747
/**
748
* Build the settings.
749
* @return the settings
750
*/
751
public BsonWriterSettings build();
752
}
753
}
754
```
755
756
## Usage Examples
757
758
### Basic Binary I/O
759
760
```java
761
import org.bson.*;
762
import org.bson.io.*;
763
import java.nio.ByteBuffer;
764
765
// Write BSON data to a buffer
766
BasicOutputBuffer outputBuffer = new BasicOutputBuffer();
767
BsonBinaryWriter writer = new BsonBinaryWriter(outputBuffer);
768
769
writer.writeStartDocument();
770
writer.writeString("name", "John Doe");
771
writer.writeInt32("age", 30);
772
writer.writeBoolean("active", true);
773
writer.writeEndDocument();
774
writer.close();
775
776
// Read BSON data from buffer
777
byte[] bytes = outputBuffer.toByteArray();
778
BsonBinaryReader reader = new BsonBinaryReader(ByteBuffer.wrap(bytes));
779
780
reader.readStartDocument();
781
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
782
String fieldName = reader.readName();
783
switch (reader.getCurrentBsonType()) {
784
case STRING:
785
String stringValue = reader.readString();
786
break;
787
case INT32:
788
int intValue = reader.readInt32();
789
break;
790
case BOOLEAN:
791
boolean boolValue = reader.readBoolean();
792
break;
793
}
794
}
795
reader.readEndDocument();
796
reader.close();
797
```
798
799
### Document Reader/Writer
800
801
```java
802
import org.bson.*;
803
804
// Write to a BsonDocument using BsonDocumentWriter
805
BsonDocument document = new BsonDocument();
806
BsonDocumentWriter docWriter = new BsonDocumentWriter(document);
807
808
docWriter.writeStartDocument();
809
docWriter.writeString("title", "BSON Example");
810
docWriter.writeStartArray("tags");
811
docWriter.writeString("mongodb");
812
docWriter.writeString("bson");
813
docWriter.writeEndArray();
814
docWriter.writeEndDocument();
815
docWriter.close();
816
817
// Read from a BsonDocument using BsonDocumentReader
818
BsonDocumentReader docReader = new BsonDocumentReader(document);
819
docReader.readStartDocument();
820
while (docReader.readBsonType() != BsonType.END_OF_DOCUMENT) {
821
String name = docReader.readName();
822
if (name.equals("title")) {
823
String title = docReader.readString();
824
} else if (name.equals("tags")) {
825
docReader.readStartArray();
826
while (docReader.readBsonType() != BsonType.END_OF_DOCUMENT) {
827
String tag = docReader.readString();
828
}
829
docReader.readEndArray();
830
}
831
}
832
docReader.readEndDocument();
833
docReader.close();
834
```
835
836
### Streaming Large Documents
837
838
```java
839
import org.bson.*;
840
import org.bson.io.*;
841
import java.io.*;
842
843
// Stream writing for large documents
844
try (FileOutputStream fos = new FileOutputStream("large-document.bson");
845
BsonBinaryWriter writer = new BsonBinaryWriter(new BasicOutputBuffer(fos))) {
846
847
writer.writeStartDocument();
848
writer.writeStartArray("items");
849
850
for (int i = 0; i < 1000000; i++) {
851
writer.writeStartDocument();
852
writer.writeInt32("id", i);
853
writer.writeString("name", "Item " + i);
854
writer.writeEndDocument();
855
}
856
857
writer.writeEndArray();
858
writer.writeEndDocument();
859
}
860
861
// Stream reading for large documents
862
try (FileInputStream fis = new FileInputStream("large-document.bson");
863
BsonBinaryReader reader = new BsonBinaryReader(ByteBuffer.wrap(fis.readAllBytes()))) {
864
865
reader.readStartDocument();
866
reader.readName(); // "items"
867
reader.readStartArray();
868
869
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
870
reader.readStartDocument();
871
reader.readName(); // "id"
872
int id = reader.readInt32();
873
reader.readName(); // "name"
874
String name = reader.readString();
875
reader.readEndDocument();
876
877
// Process item...
878
}
879
880
reader.readEndArray();
881
reader.readEndDocument();
882
}
883
```
884
885
### Mark and Reset
886
887
```java
888
BsonBinaryReader reader = new BsonBinaryReader(byteBuffer);
889
890
reader.readStartDocument();
891
BsonReaderMark mark = reader.getMark(); // Mark current position
892
893
reader.readName(); // Read first field
894
String firstField = reader.readString();
895
896
reader.reset(mark); // Reset to marked position
897
reader.readName(); // Read first field again
898
String sameField = reader.readString(); // Same value as firstField
899
```