All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.azure.core.util.BinaryData Maven / Gradle / Ivy

There is a newer version: 1.54.1
Show newest version
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.core.util;

import com.azure.core.implementation.util.BinaryDataContent;
import com.azure.core.implementation.util.BinaryDataHelper;
import com.azure.core.implementation.util.ByteArrayContent;
import com.azure.core.implementation.util.ByteBufferContent;
import com.azure.core.implementation.util.FileContent;
import com.azure.core.implementation.util.FluxByteBufferContent;
import com.azure.core.implementation.util.InputStreamContent;
import com.azure.core.implementation.util.ListByteBufferContent;
import com.azure.core.implementation.util.SerializableContent;
import com.azure.core.implementation.util.StringContent;
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.serializer.JsonSerializer;
import com.azure.core.util.serializer.JsonSerializerProvider;
import com.azure.core.util.serializer.JsonSerializerProviders;
import com.azure.core.util.serializer.ObjectSerializer;
import com.azure.core.util.serializer.TypeReference;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.function.BiConsumer;

import static com.azure.core.implementation.util.BinaryDataContent.STREAM_READ_SIZE;
import static com.azure.core.util.FluxUtil.monoError;

/**
 * BinaryData is a convenient data interchange class for use throughout the Azure SDK for Java. Put simply, BinaryData
 * enables developers to bring data in from external sources, and read it back from Azure services, in formats that
 * appeal to them. This leaves BinaryData, and the Azure SDK for Java, the task of converting this data into appropriate
 * formats to be transferred to and from these external services. This enables developers to focus on their business
 * logic, and enables the Azure SDK for Java to optimize operations for best performance.
 * 

* BinaryData in its simplest form can be thought of as a container for content. Often this content is already in-memory * as a String, byte array, or an Object that can be serialized into a String or byte[]. When the BinaryData is about to * be sent to an Azure Service, this in-memory content is copied into the network request and sent to the service. *

*

* In more performance critical scenarios, where copying data into memory results in increased memory pressure, it is * possible to create a BinaryData instance from a stream of data. From this, BinaryData can be connected directly to * the outgoing network connection so that the stream is read directly to the network, without needing to first be read * into memory on the system. Similarly, it is possible to read a stream of data from a BinaryData returned from an * Azure Service without it first being read into memory. In many situations, these streaming operations can drastically * reduce the memory pressure in applications, and so it is encouraged that all developers very carefully consider their * ability to use the most appropriate API in BinaryData whenever they encounter an client library that makes use of * BinaryData. *

*

* Refer to the documentation of each method in the BinaryData class to better understand its performance * characteristics, and refer to the samples below to understand the common usage scenarios of this class. *

* * {@link BinaryData} can be created from an {@link InputStream}, a {@link Flux} of {@link ByteBuffer}, a * {@link String}, an {@link Object}, a {@link Path file}, or a byte array. * *

A note on data mutability

* * {@link BinaryData} does not copy data on construction. BinaryData keeps a reference to the source content and is * accessed when a read request is made. So, any modifications to the underlying source before the content is read can * result in undefined behavior. *

* To create an instance of {@link BinaryData}, use the various static factory methods available. They all start with * {@code 'from'} prefix, for example {@link BinaryData#fromBytes(byte[])}. *

* *

Create an instance from a byte array

* * *
 * final byte[] data = "Some Data".getBytes(StandardCharsets.UTF_8);
 * BinaryData binaryData = BinaryData.fromBytes(data);
 * System.out.println(new String(binaryData.toBytes(), StandardCharsets.UTF_8));
 * 
* * *

Create an instance from a String

* * *
 * final String data = "Some Data";
 * // Following will use default character set as StandardCharsets.UTF_8
 * BinaryData binaryData = BinaryData.fromString(data);
 * System.out.println(binaryData.toString());
 * 
* * *

Create an instance from an InputStream

* * *
 * final ByteArrayInputStream inputStream = new ByteArrayInputStream("Some Data".getBytes(StandardCharsets.UTF_8));
 * BinaryData binaryData = BinaryData.fromStream(inputStream);
 * System.out.println(binaryData.toString());
 * 
* * *

Create an instance from an Object

* * *
 * class Person {
 *     @JsonProperty
 *     private String name;
 *
 *     @JsonSetter
 *     public Person setName(String name) {
 *         this.name = name;
 *         return this;
 *     }
 *
 *     @JsonGetter
 *     public String getName() {
 *         return name;
 *     }
 * }
 * final Person data = new Person().setName("John");
 *
 * // Provide your custom serializer or use Azure provided serializers.
 * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
 * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
 * BinaryData binaryData = BinaryData.fromObject(data);
 *
 * System.out.println(binaryData.toString());
 * 
* * *

Create an instance from {@code Flux}

* * *
 * final byte[] data = "Some Data".getBytes(StandardCharsets.UTF_8);
 * final Flux<ByteBuffer> dataFlux = Flux.just(ByteBuffer.wrap(data));
 *
 * Mono<BinaryData> binaryDataMono = BinaryData.fromFlux(dataFlux);
 *
 * Disposable subscriber = binaryDataMono
 *     .map(binaryData -> {
 *         System.out.println(binaryData.toString());
 *         return true;
 *     })
 *     .subscribe();
 *
 * // So that your program wait for above subscribe to complete.
 * TimeUnit.SECONDS.sleep(5);
 * subscriber.dispose();
 * 
* * *

Create an instance from a file

* * *
 * BinaryData binaryData = BinaryData.fromFile(new File("path/to/file").toPath());
 * System.out.println(new String(binaryData.toBytes(), StandardCharsets.UTF_8));
 * 
* * * @see ObjectSerializer * @see JsonSerializer * @see More about serialization */ public final class BinaryData { private static final ClientLogger LOGGER = new ClientLogger(BinaryData.class); static final JsonSerializer SERIALIZER = JsonSerializerProviders.createInstance(true); static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private final BinaryDataContent content; BinaryData(BinaryDataContent content) { this.content = Objects.requireNonNull(content, "'content' cannot be null."); } static { BinaryDataHelper.setAccessor(new BinaryDataHelper.BinaryDataAccessor() { @Override public BinaryData createBinaryData(BinaryDataContent content) { return new BinaryData(content); } @Override public BinaryDataContent getContent(BinaryData binaryData) { return binaryData.content; } }); } /** * Creates an instance of {@link BinaryData} from the given {@link InputStream}. Depending on the type of * inputStream, the BinaryData instance created may or may not allow reading the content more than once. The stream * content is not cached if the stream is not read into a format that requires the content to be fully read into * memory. *

* NOTE: The {@link InputStream} is not closed by this function. *

* *

Create an instance from an InputStream

* * *
     * final ByteArrayInputStream inputStream = new ByteArrayInputStream("Some Data".getBytes(StandardCharsets.UTF_8));
     * BinaryData binaryData = BinaryData.fromStream(inputStream);
     * System.out.println(binaryData.toString());
     * 
* * * @param inputStream The {@link InputStream} that {@link BinaryData} will represent. * @return A {@link BinaryData} representing the {@link InputStream}. * @throws UncheckedIOException If any error happens while reading the {@link InputStream}. * @throws NullPointerException If {@code inputStream} is null. */ public static BinaryData fromStream(InputStream inputStream) { return fromStream(inputStream, null); } /** * Creates an instance of {@link BinaryData} from the given {@link InputStream}. Depending on the type of * inputStream, the BinaryData instance created may or may not allow reading the content more than once. The stream * content is not cached if the stream is not read into a format that requires the content to be fully read into * memory. *

* NOTE: The {@link InputStream} is not closed by this function. *

* *

Create an instance from an InputStream

* * *
     * byte[] bytes = "Some Data".getBytes(StandardCharsets.UTF_8);
     * final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
     * BinaryData binaryData = BinaryData.fromStream(inputStream, (long) bytes.length);
     * System.out.println(binaryData.toString());
     * 
* * * @param inputStream The {@link InputStream} that {@link BinaryData} will represent. * @param length The length of {@code data} in bytes. * @return A {@link BinaryData} representing the {@link InputStream}. * @throws UncheckedIOException If any error happens while reading the {@link InputStream}. * @throws NullPointerException If {@code inputStream} is null. */ public static BinaryData fromStream(InputStream inputStream, Long length) { return new BinaryData(new InputStreamContent(inputStream, length)); } /** * Creates an instance of {@link BinaryData} from the given {@link InputStream}. * NOTE: The {@link InputStream} is not closed by this function. * *

Create an instance from an InputStream

* * *
     * final ByteArrayInputStream inputStream = new ByteArrayInputStream("Some Data".getBytes(StandardCharsets.UTF_8));
     *
     * Mono<BinaryData> binaryDataMono = BinaryData.fromStreamAsync(inputStream);
     *
     * Disposable subscriber = binaryDataMono
     *     .map(binaryData -> {
     *         System.out.println(binaryData.toString());
     *         return true;
     *     })
     *     .subscribe();
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param inputStream The {@link InputStream} that {@link BinaryData} will represent. * @return A {@link Mono} of {@link BinaryData} representing the {@link InputStream}. * @throws UncheckedIOException If any error happens while reading the {@link InputStream}. * @throws NullPointerException If {@code inputStream} is null. */ public static Mono fromStreamAsync(InputStream inputStream) { return fromStreamAsync(inputStream, null); } /** * Creates an instance of {@link BinaryData} from the given {@link InputStream}. * NOTE: The {@link InputStream} is not closed by this function. * *

Create an instance from an InputStream

* * *
     * byte[] bytes = "Some Data".getBytes(StandardCharsets.UTF_8);
     * final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
     *
     * Mono<BinaryData> binaryDataMono = BinaryData.fromStreamAsync(inputStream, (long) bytes.length);
     *
     * Disposable subscriber = binaryDataMono
     *     .map(binaryData -> {
     *         System.out.println(binaryData.toString());
     *         return true;
     *     })
     *     .subscribe();
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param inputStream The {@link InputStream} that {@link BinaryData} will represent. * @param length The length of {@code data} in bytes. * @return A {@link Mono} of {@link BinaryData} representing the {@link InputStream}. * @throws UncheckedIOException If any error happens while reading the {@link InputStream}. * @throws NullPointerException If {@code inputStream} is null. */ public static Mono fromStreamAsync(InputStream inputStream, Long length) { return Mono.fromCallable(() -> fromStream(inputStream, length)); } /** * Creates an instance of {@link BinaryData} from the given {@link Flux} of {@link ByteBuffer}. * *

Create an instance from a Flux of ByteBuffer

* *

This method aggregates data into single byte array.

* * *
     * final byte[] data = "Some Data".getBytes(StandardCharsets.UTF_8);
     * final Flux<ByteBuffer> dataFlux = Flux.just(ByteBuffer.wrap(data));
     *
     * Mono<BinaryData> binaryDataMono = BinaryData.fromFlux(dataFlux);
     *
     * Disposable subscriber = binaryDataMono
     *     .map(binaryData -> {
     *         System.out.println(binaryData.toString());
     *         return true;
     *     })
     *     .subscribe();
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param data The {@link Flux} of {@link ByteBuffer} that {@link BinaryData} will represent. * @return A {@link Mono} of {@link BinaryData} representing the {@link Flux} of {@link ByteBuffer}. * @throws NullPointerException If {@code data} is null. */ public static Mono fromFlux(Flux data) { return fromFlux(data, null); } /** * Creates an instance of {@link BinaryData} from the given {@link Flux} of {@link ByteBuffer}. * *

Create an instance from a Flux of ByteBuffer

* *

This method aggregates data into single byte array.

* * *
     * final byte[] data = "Some Data".getBytes(StandardCharsets.UTF_8);
     * final long length = data.length;
     * final Flux<ByteBuffer> dataFlux = Flux.just(ByteBuffer.wrap(data));
     *
     * Mono<BinaryData> binaryDataMono = BinaryData.fromFlux(dataFlux, length);
     *
     * Disposable subscriber = binaryDataMono
     *     .map(binaryData -> {
     *         System.out.println(binaryData.toString());
     *         return true;
     *     })
     *     .subscribe();
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param data The {@link Flux} of {@link ByteBuffer} that {@link BinaryData} will represent. * @param length The length of {@code data} in bytes. * @return A {@link Mono} of {@link BinaryData} representing the {@link Flux} of {@link ByteBuffer}. * @throws IllegalArgumentException if the length is less than zero. * @throws NullPointerException if {@code data} is null. */ public static Mono fromFlux(Flux data, Long length) { return fromFlux(data, length, true); } /** * Creates an instance of {@link BinaryData} from the given {@link Flux} of {@link ByteBuffer}. *

* If {@code bufferContent} is true and {@code length} is null the length of the returned {@link BinaryData} will be * based on the length calculated by buffering. If {@code length} is non-null it will always be used as the * {@link BinaryData} length even if buffering determines a different length. * *

Create an instance from a Flux of ByteBuffer

* * *
     * final byte[] data = "Some Data".getBytes(StandardCharsets.UTF_8);
     * final long length = data.length;
     * final boolean shouldAggregateData = false;
     * final Flux<ByteBuffer> dataFlux = Flux.just(ByteBuffer.wrap(data));
     *
     * Mono<BinaryData> binaryDataMono = BinaryData.fromFlux(dataFlux, length, shouldAggregateData);
     *
     * Disposable subscriber = binaryDataMono
     *     .map(binaryData -> {
     *         System.out.println(binaryData.toString());
     *         return true;
     *     })
     *     .subscribe();
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param data The {@link Flux} of {@link ByteBuffer} that {@link BinaryData} will represent. * @param length The length of {@code data} in bytes. * @param bufferContent A flag indicating whether {@link Flux} should be buffered eagerly or consumption deferred. * @return A {@link Mono} of {@link BinaryData} representing the {@link Flux} of {@link ByteBuffer}. * @throws IllegalArgumentException if the length is less than zero. * @throws NullPointerException if {@code data} is null. */ public static Mono fromFlux(Flux data, Long length, boolean bufferContent) { if (data == null) { return monoError(LOGGER, new NullPointerException("'data' cannot be null.")); } if (length != null && length < 0) { return monoError(LOGGER, new IllegalArgumentException("'length' cannot be less than 0.")); } if (!bufferContent) { return Mono.just(new BinaryData(new FluxByteBufferContent(data, length))); } // Buffer the Flux content using ByteBuffers of equal size to the original ByteBuffer. // Previously this was using FluxUtil.collectBytesInByteBufferStream which runs into two issues: // // 1. The content is limited in size as it collects into a byte array which is limited to ~2GB in size. // 2. This could lead to a very large chunk of data existing which can cause pauses when allocating large // arrays. long[] trueLength = new long[]{0}; return data.map(buffer -> { int bufferSize = buffer.remaining(); ByteBuffer copy = ByteBuffer.allocate(bufferSize); trueLength[0] += bufferSize; copy.put(buffer); copy.flip(); return copy; }) .collect(LinkedList::new, (BiConsumer, ByteBuffer>) LinkedList::add) .map(buffers -> { // TODO (alzimmer): What should be done when length != null but it differs from the true length // seen when doing the buffering. return new BinaryData(new FluxByteBufferContent(Flux.fromIterable(buffers).map(ByteBuffer::duplicate), (length != null) ? length : trueLength[0], true)); }); } /** * Creates an instance of {@link BinaryData} from the given {@link String}. *

* The {@link String} is converted into bytes using {@link String#getBytes(Charset)} passing * {@link StandardCharsets#UTF_8}. *

*

Create an instance from a String

* * *
     * final String data = "Some Data";
     * // Following will use default character set as StandardCharsets.UTF_8
     * BinaryData binaryData = BinaryData.fromString(data);
     * System.out.println(binaryData.toString());
     * 
* * * @param data The {@link String} that {@link BinaryData} will represent. * @return A {@link BinaryData} representing the {@link String}. * @throws NullPointerException If {@code data} is null. */ public static BinaryData fromString(String data) { return new BinaryData(new StringContent(data)); } /** * Creates an instance of {@link BinaryData} from the given byte array. *

* If the byte array is zero length an empty {@link BinaryData} will be returned. Note that the input byte array is * used as a reference by this instance of {@link BinaryData} and any changes to the byte array outside of this * instance will result in the contents of this BinaryData instance being updated as well. To safely update the byte * array without impacting the BinaryData instance, perform an array copy first. *

* *

Create an instance from a byte array

* * *
     * final byte[] data = "Some Data".getBytes(StandardCharsets.UTF_8);
     * BinaryData binaryData = BinaryData.fromBytes(data);
     * System.out.println(new String(binaryData.toBytes(), StandardCharsets.UTF_8));
     * 
* * * @param data The byte array that {@link BinaryData} will represent. * @return A {@link BinaryData} representing the byte array. * @throws NullPointerException If {@code data} is null. */ public static BinaryData fromBytes(byte[] data) { return new BinaryData(new ByteArrayContent(data)); } /** * Creates an instance of {@link BinaryData} from the given {@link ByteBuffer}. *

* If the {@link ByteBuffer} is zero length an empty {@link BinaryData} will be returned. Note that the input * {@link ByteBuffer} is used as a reference by this instance of {@link BinaryData} and any changes to the * {@link ByteBuffer} outside of this instance will result in the contents of this BinaryData instance being updated * as well. To safely update the {@link ByteBuffer} without impacting the BinaryData instance, perform an array copy * first. *

* *

Create an instance from a ByteBuffer

* * *
     * final ByteBuffer data = ByteBuffer.wrap("Some Data".getBytes(StandardCharsets.UTF_8));
     * BinaryData binaryData = BinaryData.fromByteBuffer(data);
     * System.out.println(binaryData);
     * 
* * * @param data The {@link ByteBuffer} that {@link BinaryData} will represent. * @return A {@link BinaryData} representing the {@link ByteBuffer}. * @throws NullPointerException If {@code data} is null. */ public static BinaryData fromByteBuffer(ByteBuffer data) { return new BinaryData(new ByteBufferContent(data)); } /** * Creates an instance of {@link BinaryData} from the given {@link List} of {@link ByteBuffer}. * *

* The input {@link ByteBuffer} instances are used as a reference by this instance of {@link BinaryData} and any * changes to a {@link ByteBuffer} outside of this instance will result in the contents of this BinaryData instance * being updated as well. To safely update the byte array without impacting the BinaryData instance, perform an * array copy first. *

* *

Create an instance from a List<ByteBuffer>

* * *
     * final List<ByteBuffer> data = Stream.of("Some ", "data")
     *     .map(s -> ByteBuffer.wrap(s.getBytes(StandardCharsets.UTF_8)))
     *     .collect(Collectors.toList());
     * BinaryData binaryData = BinaryData.fromListByteBuffer(data);
     * System.out.println(binaryData);
     * 
* * * @param data The {@link List} of {@link ByteBuffer} that {@link BinaryData} will represent. * @return A {@link BinaryData} representing the {@link List} of {@link ByteBuffer}. */ public static BinaryData fromListByteBuffer(List data) { return new BinaryData(new ListByteBufferContent(data)); } /** * Creates an instance of {@link BinaryData} by serializing the {@link Object} using the default * {@link JsonSerializer}. * *

* Note: This method first looks for a {@link JsonSerializerProvider} implementation on the classpath. If no * implementation is found, a default Jackson-based implementation will be used to serialize the object. *

*

Creating an instance from an Object

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Provide your custom serializer or use Azure provided serializers.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     * BinaryData binaryData = BinaryData.fromObject(data);
     *
     * System.out.println(binaryData.toString());
     * 
* * * @param data The object that will be JSON serialized that {@link BinaryData} will represent. * @return A {@link BinaryData} representing the JSON serialized object. * @throws NullPointerException If {@code data} is null. * @see JsonSerializer */ public static BinaryData fromObject(Object data) { return fromObject(data, SERIALIZER); } /** * Creates an instance of {@link BinaryData} by serializing the {@link Object} using the default * {@link JsonSerializer}. * *

* Note: This method first looks for a {@link JsonSerializerProvider} implementation on the classpath. If no * implementation is found, a default Jackson-based implementation will be used to serialize the object. *

*

Creating an instance from an Object

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Provide your custom serializer or use Azure provided serializers.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     * Disposable subscriber = BinaryData.fromObjectAsync(data)
     *     .subscribe(binaryData -> System.out.println(binaryData.toString()));
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param data The object that will be JSON serialized that {@link BinaryData} will represent. * @return A {@link Mono} of {@link BinaryData} representing the JSON serialized object. * @see JsonSerializer */ public static Mono fromObjectAsync(Object data) { return fromObjectAsync(data, SERIALIZER); } /** * Creates an instance of {@link BinaryData} by serializing the {@link Object} using the passed * {@link ObjectSerializer}. *

* The passed {@link ObjectSerializer} can either be one of the implementations offered by the Azure SDKs or your * own implementation. *

* *

Azure SDK implementations

* * *

Create an instance from an Object

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Provide your custom serializer or use Azure provided serializers.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     * final ObjectSerializer serializer =
     *     new MyJsonSerializer(); // Replace this with your Serializer
     * BinaryData binaryData = BinaryData.fromObject(data, serializer);
     *
     * System.out.println(binaryData.toString());
     * 
* * * @param data The object that will be serialized that {@link BinaryData} will represent. The {@code serializer} * determines how {@code null} data is serialized. * @param serializer The {@link ObjectSerializer} used to serialize object. * @return A {@link BinaryData} representing the serialized object. * @throws NullPointerException If {@code serializer} is null. * @see ObjectSerializer * @see JsonSerializer * @see More about serialization */ public static BinaryData fromObject(Object data, ObjectSerializer serializer) { return new BinaryData(new SerializableContent(data, serializer)); } /** * Creates an instance of {@link BinaryData} by serializing the {@link Object} using the passed * {@link ObjectSerializer}. * *

* The passed {@link ObjectSerializer} can either be one of the implementations offered by the Azure SDKs or your * own implementation. *

* *

Azure SDK implementations

* * *

Create an instance from an Object

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Provide your custom serializer or use Azure provided serializers.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     * final ObjectSerializer serializer =
     *     new MyJsonSerializer(); // Replace this with your Serializer
     * Disposable subscriber = BinaryData.fromObjectAsync(data, serializer)
     *     .subscribe(binaryData -> System.out.println(binaryData.toString()));
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param data The object that will be serialized that {@link BinaryData} will represent. The {@code serializer} * determines how {@code null} data is serialized. * @param serializer The {@link ObjectSerializer} used to serialize object. * @return A {@link Mono} of {@link BinaryData} representing the serialized object. * @throws NullPointerException If {@code serializer} is null. * @see ObjectSerializer * @see JsonSerializer * @see More about serialization */ public static Mono fromObjectAsync(Object data, ObjectSerializer serializer) { return Mono.fromCallable(() -> fromObject(data, serializer)); } /** * Creates a {@link BinaryData} that uses the content of the file at {@link Path} as its data. This method checks * for the existence of the file at the time of creating an instance of {@link BinaryData}. The file, however, is * not read until there is an attempt to read the contents of the returned BinaryData instance. * *

Create an instance from a file

* *

The {@link BinaryData} returned from this method uses 8KB chunk size when reading file content.

* * *
     * BinaryData binaryData = BinaryData.fromFile(new File("path/to/file").toPath());
     * System.out.println(new String(binaryData.toBytes(), StandardCharsets.UTF_8));
     * 
* * * @param file The {@link Path} that will be the {@link BinaryData} data. * @return A new {@link BinaryData}. * @throws NullPointerException If {@code file} is null. */ public static BinaryData fromFile(Path file) { return fromFile(file, STREAM_READ_SIZE); } /** * Creates a {@link BinaryData} that uses the content of the file at {@link Path file} as its data. This method * checks for the existence of the file at the time of creating an instance of {@link BinaryData}. The file, * however, is not read until there is an attempt to read the contents of the returned BinaryData instance. * *

Create an instance from a file

* * *
     * BinaryData binaryData = BinaryData.fromFile(new File("path/to/file").toPath(), 8092);
     * System.out.println(new String(binaryData.toBytes(), StandardCharsets.UTF_8));
     * 
* * * @param file The {@link Path} that will be the {@link BinaryData} data. * @param chunkSize The requested size for each read of the path. * @return A new {@link BinaryData}. * @throws NullPointerException If {@code file} is null. * @throws IllegalArgumentException If {@code offset} or {@code length} are negative or {@code offset} plus * {@code length} is greater than the file size or {@code chunkSize} is less than or equal to 0. * @throws UncheckedIOException if the file does not exist. */ public static BinaryData fromFile(Path file, int chunkSize) { return new BinaryData(new FileContent(file, chunkSize, null, null)); } /** * Creates a {@link BinaryData} that uses the content of the file at {@link Path file} as its data. This method * checks for the existence of the file at the time of creating an instance of {@link BinaryData}. The file, * however, is not read until there is an attempt to read the contents of the returned BinaryData instance. * *

Create an instance from a file

* *

The {@link BinaryData} returned from this method uses 8KB chunk size when reading file content.

* * *
     * long position = 1024;
     * long length = 100 * 1048;
     * BinaryData binaryData = BinaryData.fromFile(
     *     new File("path/to/file").toPath(), position, length);
     * System.out.println(new String(binaryData.toBytes(), StandardCharsets.UTF_8));
     * 
* * * @param file The {@link Path} that will be the {@link BinaryData} data. * @param position Position, or offset, within the path where reading begins. * @param length Maximum number of bytes to be read from the path. * @return A new {@link BinaryData}. * @throws NullPointerException If {@code file} is null. * @throws IllegalArgumentException If {@code offset} or {@code length} are negative or {@code offset} plus * {@code length} is greater than the file size or {@code chunkSize} is less than or equal to 0. * @throws UncheckedIOException if the file does not exist. */ public static BinaryData fromFile(Path file, Long position, Long length) { return new BinaryData(new FileContent(file, STREAM_READ_SIZE, position, length)); } /** * Creates a {@link BinaryData} that uses the content of the file at {@link Path file} as its data. This method * checks for the existence of the file at the time of creating an instance of {@link BinaryData}. The file, * however, is not read until there is an attempt to read the contents of the returned BinaryData instance. * *

Create an instance from a file

* * *
     * long position = 1024;
     * long length = 100 * 1048;
     * int chunkSize = 8092;
     * BinaryData binaryData = BinaryData.fromFile(
     *     new File("path/to/file").toPath(), position, length, chunkSize);
     * System.out.println(new String(binaryData.toBytes(), StandardCharsets.UTF_8));
     * 
* * * @param file The {@link Path} that will be the {@link BinaryData} data. * @param position Position, or offset, within the path where reading begins. * @param length Maximum number of bytes to be read from the path. * @param chunkSize The requested size for each read of the path. * @return A new {@link BinaryData}. * @throws NullPointerException If {@code file} is null. * @throws IllegalArgumentException If {@code offset} or {@code length} are negative or {@code offset} plus * {@code length} is greater than the file size or {@code chunkSize} is less than or equal to 0. * @throws UncheckedIOException if the file does not exist. */ public static BinaryData fromFile(Path file, Long position, Long length, int chunkSize) { return new BinaryData(new FileContent(file, chunkSize, position, length)); } /** * Returns a byte array representation of this {@link BinaryData}. *

* This method returns a reference to the underlying byte array. Modifying the contents of the returned byte array * may change the content of this BinaryData instance. If the content source of this BinaryData instance is a file, * an {@link InputStream}, or a {@code Flux} the source is not modified. To safely update the byte * array, it is recommended to make a copy of the contents first. *

* If the {@link BinaryData} is larger than the maximum size allowed for a {@code byte[]} this will throw an * {@link IllegalStateException}. * * @return A byte array representing this {@link BinaryData}. * @throws IllegalStateException If the {@link BinaryData} is larger than the maximum size allowed for a * {@code byte[]}. */ public byte[] toBytes() { return content.toBytes(); } /** * Returns a {@link String} representation of this {@link BinaryData} by converting its data using the UTF-8 * character set. A new instance of String is created each time this method is called. *

* If the {@link BinaryData} is larger than the maximum size allowed for a {@link String} this will throw an * {@link IllegalStateException}. * * @return A {@link String} representing this {@link BinaryData}. * @throws IllegalStateException If the {@link BinaryData} is larger than the maximum size allowed for a * {@link String}. */ public String toString() { return content.toString(); } /** * Returns an {@link Object} representation of this {@link BinaryData} by deserializing its data using the default * {@link JsonSerializer}. Each time this method is called, the content is deserialized and a new instance of type * {@code T} is returned. So, calling this method repeatedly to convert the underlying data source into the same * type is not recommended. *

* The type, represented by {@link Class}, should be a non-generic class, for generic classes use * {@link #toObject(TypeReference)}. *

* Note: This method first looks for a {@link JsonSerializerProvider} implementation on the classpath. If no * implementation is found, a default Jackson-based implementation will be used to deserialize the object. * *

Get a non-generic Object from the BinaryData

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Ensure your classpath have the Serializer to serialize the object which implement implement
     * // com.azure.core.util.serializer.JsonSerializer interface.
     * // Or use Azure provided libraries for this.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     * BinaryData binaryData = BinaryData.fromObject(data);
     *
     * Person person = binaryData.toObject(Person.class);
     * System.out.println(person.getName());
     * 
* * * @param Type of the deserialized Object. * @param clazz The {@link Class} representing the Object's type. * @return An {@link Object} representing the JSON deserialized {@link BinaryData}. * @throws NullPointerException If {@code clazz} is null. * @see JsonSerializer */ public T toObject(Class clazz) { return toObject(TypeReference.createInstance(clazz), SERIALIZER); } /** * Returns an {@link Object} representation of this {@link BinaryData} by deserializing its data using the default * {@link JsonSerializer}. Each time this method is called, the content is deserialized and a new instance of type * {@code T} is returned. So, calling this method repeatedly to convert the underlying data source into the same * type is not recommended. *

* The type, represented by {@link TypeReference}, can either be a generic or non-generic type. If the type is * generic create a sub-type of {@link TypeReference}, if the type is non-generic use * {@link TypeReference#createInstance(Class)}. *

* Note: This method first looks for a {@link JsonSerializerProvider} implementation on the classpath. If no * implementation is found, a default Jackson-based implementation will be used to deserialize the object. * *

Get a non-generic Object from the BinaryData

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Ensure your classpath have the Serializer to serialize the object which implement implement
     * // com.azure.core.util.serializer.JsonSerializer interface.
     * // Or use Azure provided libraries for this.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     * BinaryData binaryData = BinaryData.fromObject(data);
     *
     * Person person = binaryData.toObject(TypeReference.createInstance(Person.class));
     * System.out.println(person.getName());
     * 
* * *

Get a generic Object from the BinaryData

* * *
     * final Person person1 = new Person().setName("John");
     * final Person person2 = new Person().setName("Jack");
     *
     * List<Person> personList = new ArrayList<>();
     * personList.add(person1);
     * personList.add(person2);
     *
     * // Ensure your classpath have the Serializer to serialize the object which implement implement
     * // com.azure.core.util.serializer.JsonSerializer interface.
     * // Or use Azure provided libraries for this.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     *
     * BinaryData binaryData = BinaryData.fromObject(personList);
     *
     * List<Person> persons = binaryData.toObject(new TypeReference<List<Person>>() { });
     * persons.forEach(person -> System.out.println(person.getName()));
     * 
* * * @param typeReference The {@link TypeReference} representing the Object's type. * @param Type of the deserialized Object. * @return An {@link Object} representing the JSON deserialized {@link BinaryData}. * @throws NullPointerException If {@code typeReference} is null. * @see JsonSerializer */ public T toObject(TypeReference typeReference) { return toObject(typeReference, SERIALIZER); } /** * Returns an {@link Object} representation of this {@link BinaryData} by deserializing its data using the passed * {@link ObjectSerializer}. Each time this method is called, the content is deserialized and a new instance of type * {@code T} is returned. So, calling this method repeatedly to convert the underlying data source into the same * type is not recommended. *

* The type, represented by {@link Class}, should be a non-generic class, for generic classes use * {@link #toObject(TypeReference, ObjectSerializer)}. *

* The passed {@link ObjectSerializer} can either be one of the implementations offered by the Azure SDKs or your * own implementation. * *

Azure SDK implementations

* * *

Get a non-generic Object from the BinaryData

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Provide your custom serializer or use Azure provided serializers.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     * final ObjectSerializer serializer =
     *     new MyJsonSerializer(); // Replace this with your Serializer
     * BinaryData binaryData = BinaryData.fromObject(data, serializer);
     *
     * Person person = binaryData.toObject(Person.class, serializer);
     * System.out.println("Name : " + person.getName());
     * 
* * * @param clazz The {@link Class} representing the Object's type. * @param serializer The {@link ObjectSerializer} used to deserialize object. * @param Type of the deserialized Object. * @return An {@link Object} representing the deserialized {@link BinaryData}. * @throws NullPointerException If {@code clazz} or {@code serializer} is null. * @see ObjectSerializer * @see JsonSerializer * @see More about serialization */ public T toObject(Class clazz, ObjectSerializer serializer) { return toObject(TypeReference.createInstance(clazz), serializer); } /** * Returns an {@link Object} representation of this {@link BinaryData} by deserializing its data using the passed * {@link ObjectSerializer}. Each time this method is called, the content is deserialized and a new instance of type * {@code T} is returned. So, calling this method repeatedly to convert the underlying data source into the same * type is not recommended. *

* The type, represented by {@link TypeReference}, can either be a generic or non-generic type. If the type is * generic create a sub-type of {@link TypeReference}, if the type is non-generic use * {@link TypeReference#createInstance(Class)}. *

* The passed {@link ObjectSerializer} can either be one of the implementations offered by the Azure SDKs or your * own implementation. * *

Azure SDK implementations

* * *

Get a non-generic Object from the BinaryData

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Provide your custom serializer or use Azure provided serializers.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     * final ObjectSerializer serializer =
     *     new MyJsonSerializer(); // Replace this with your Serializer
     * BinaryData binaryData = BinaryData.fromObject(data, serializer);
     *
     * Person person = binaryData.toObject(TypeReference.createInstance(Person.class), serializer);
     * System.out.println("Name : " + person.getName());
     *
     * 
* * *

Get a generic Object from the BinaryData

* * *
     * final Person person1 = new Person().setName("John");
     * final Person person2 = new Person().setName("Jack");
     *
     * List<Person> personList = new ArrayList<>();
     * personList.add(person1);
     * personList.add(person2);
     *
     * final ObjectSerializer serializer =
     *     new MyJsonSerializer(); // Replace this with your Serializer
     * BinaryData binaryData = BinaryData.fromObject(personList, serializer);
     *
     * // Retains the type of the list when deserializing
     * List<Person> persons = binaryData.toObject(new TypeReference<List<Person>>() { }, serializer);
     * persons.forEach(person -> System.out.println("Name : " + person.getName()));
     * 
* * * @param typeReference The {@link TypeReference} representing the Object's type. * @param serializer The {@link ObjectSerializer} used to deserialize object. * @param Type of the deserialized Object. * @return An {@link Object} representing the deserialized {@link BinaryData}. * @throws NullPointerException If {@code typeReference} or {@code serializer} is null. * @see ObjectSerializer * @see JsonSerializer * @see More about serialization */ public T toObject(TypeReference typeReference, ObjectSerializer serializer) { Objects.requireNonNull(typeReference, "'typeReference' cannot be null."); Objects.requireNonNull(serializer, "'serializer' cannot be null."); return content.toObject(typeReference, serializer); } /** * Returns an {@link Object} representation of this {@link BinaryData} by deserializing its data using the default * {@link JsonSerializer}. Each time this method is called, the content is deserialized and a new instance of type * {@code T} is returned. So, calling this method repeatedly to convert the underlying data source into the same * type is not recommended. *

* The type, represented by {@link Class}, should be a non-generic class, for generic classes use * {@link #toObject(TypeReference)}. *

* Note: This method first looks for a {@link JsonSerializerProvider} implementation on the classpath. If no * implementation is found, a default Jackson-based implementation will be used to deserialize the object. * *

Get a non-generic Object from the BinaryData

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Ensure your classpath have the Serializer to serialize the object which implement implement
     * // com.azure.core.util.serializer.JsonSerializer interface.
     * // Or use Azure provided libraries for this.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     * BinaryData binaryData = BinaryData.fromObject(data);
     *
     * Disposable subscriber = binaryData.toObjectAsync(Person.class)
     *     .subscribe(person -> System.out.println(person.getName()));
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param clazz The {@link Class} representing the Object's type. * @param Type of the deserialized Object. * @return A {@link Mono} of {@link Object} representing the JSON deserialized {@link BinaryData}. * @throws NullPointerException If {@code clazz} is null. * @see JsonSerializer */ public Mono toObjectAsync(Class clazz) { return toObjectAsync(TypeReference.createInstance(clazz), SERIALIZER); } /** * Returns an {@link Object} representation of this {@link BinaryData} by deserializing its data using the default * {@link JsonSerializer}. Each time this method is called, the content is deserialized and a new instance of type * {@code T} is returned. So, calling this method repeatedly to convert the underlying data source into the same * type is not recommended. *

* The type, represented by {@link TypeReference}, can either be a generic or non-generic type. If the type is * generic create a sub-type of {@link TypeReference}, if the type is non-generic use * {@link TypeReference#createInstance(Class)}. *

* Note: This method first looks for a {@link JsonSerializerProvider} implementation on the classpath. If no * implementation is found, a default Jackson-based implementation will be used to deserialize the object. * *

Get a non-generic Object from the BinaryData

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Ensure your classpath have the Serializer to serialize the object which implement implement
     * // com.azure.core.util.serializer.JsonSerializer interface.
     * // Or use Azure provided libraries for this.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     * BinaryData binaryData = BinaryData.fromObject(data);
     *
     * Disposable subscriber = binaryData.toObjectAsync(TypeReference.createInstance(Person.class))
     *     .subscribe(person -> System.out.println(person.getName()));
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * *

Get a generic Object from the BinaryData

* * *
     * final Person person1 = new Person().setName("John");
     * final Person person2 = new Person().setName("Jack");
     *
     * List<Person> personList = new ArrayList<>();
     * personList.add(person1);
     * personList.add(person2);
     *
     * BinaryData binaryData = BinaryData.fromObject(personList);
     *
     * Disposable subscriber = binaryData.toObjectAsync(new TypeReference<List<Person>>() { })
     *     .subscribe(persons -> persons.forEach(person -> System.out.println(person.getName())));
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param typeReference The {@link TypeReference} representing the Object's type. * @param Type of the deserialized Object. * @return A {@link Mono} of {@link Object} representing the JSON deserialized {@link BinaryData}. * @throws NullPointerException If {@code typeReference} is null. * @see JsonSerializer */ public Mono toObjectAsync(TypeReference typeReference) { return toObjectAsync(typeReference, SERIALIZER); } /** * Returns an {@link Object} representation of this {@link BinaryData} by deserializing its data using the passed * {@link ObjectSerializer}. Each time this method is called, the content is deserialized and a new instance of type * {@code T} is returned. So, calling this method repeatedly to convert the underlying data source into the same * type is not recommended. *

* The type, represented by {@link Class}, should be a non-generic class, for generic classes use * {@link #toObject(TypeReference, ObjectSerializer)}. *

* The passed {@link ObjectSerializer} can either be one of the implementations offered by the Azure SDKs or your * own implementation. * *

Azure SDK implementations

* * *

Get a non-generic Object from the BinaryData

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Provide your custom serializer or use Azure provided serializers.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     * final ObjectSerializer serializer =
     *     new MyJsonSerializer(); // Replace this with your Serializer
     * BinaryData binaryData = BinaryData.fromObject(data, serializer);
     *
     * Disposable subscriber = binaryData.toObjectAsync(Person.class, serializer)
     *     .subscribe(person -> System.out.println(person.getName()));
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param clazz The {@link Class} representing the Object's type. * @param serializer The {@link ObjectSerializer} used to deserialize object. * @param Type of the deserialized Object. * @return A {@link Mono} of {@link Object} representing the deserialized {@link BinaryData}. * @throws NullPointerException If {@code clazz} or {@code serializer} is null. * @see ObjectSerializer * @see JsonSerializer * @see More about serialization */ public Mono toObjectAsync(Class clazz, ObjectSerializer serializer) { return toObjectAsync(TypeReference.createInstance(clazz), serializer); } /** * Returns an {@link Object} representation of this {@link BinaryData} by deserializing its data using the passed * {@link ObjectSerializer}. Each time this method is called, the content is deserialized and a new instance of type * {@code T} is returned. So, calling this method repeatedly to convert the underlying data source into the same * type is not recommended. *

* The type, represented by {@link TypeReference}, can either be a generic or non-generic type. If the type is * generic create a sub-type of {@link TypeReference}, if the type is non-generic use * {@link TypeReference#createInstance(Class)}. *

* The passed {@link ObjectSerializer} can either be one of the implementations offered by the Azure SDKs or your * own implementation. * *

Azure SDK implementations

* * *

Get a non-generic Object from the BinaryData

* * *
     * class Person {
     *     @JsonProperty
     *     private String name;
     *
     *     @JsonSetter
     *     public Person setName(String name) {
     *         this.name = name;
     *         return this;
     *     }
     *
     *     @JsonGetter
     *     public String getName() {
     *         return name;
     *     }
     * }
     * final Person data = new Person().setName("John");
     *
     * // Provide your custom serializer or use Azure provided serializers.
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-jackson or
     * // https://mvnrepository.com/artifact/com.azure/azure-core-serializer-json-gson
     *
     * final ObjectSerializer serializer =
     *     new MyJsonSerializer(); // Replace this with your Serializer
     * BinaryData binaryData = BinaryData.fromObject(data, serializer);
     *
     * Disposable subscriber = binaryData
     *     .toObjectAsync(TypeReference.createInstance(Person.class), serializer)
     *     .subscribe(person -> System.out.println(person.getName()));
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * *

Get a generic Object from the BinaryData

* * *
     * final Person person1 = new Person().setName("John");
     * final Person person2 = new Person().setName("Jack");
     *
     * List<Person> personList = new ArrayList<>();
     * personList.add(person1);
     * personList.add(person2);
     *
     * final ObjectSerializer serializer =
     *     new MyJsonSerializer(); // Replace this with your Serializer
     * BinaryData binaryData = BinaryData.fromObject(personList, serializer);
     *
     * Disposable subscriber = binaryData
     *     .toObjectAsync(new TypeReference<List<Person>>() { }, serializer) // retains the generic type information
     *     .subscribe(persons -> persons.forEach(person -> System.out.println(person.getName())));
     *
     * // So that your program wait for above subscribe to complete.
     * TimeUnit.SECONDS.sleep(5);
     * subscriber.dispose();
     * 
* * * @param typeReference The {@link TypeReference} representing the Object's type. * @param serializer The {@link ObjectSerializer} used to deserialize object. * @param Type of the deserialized Object. * @return A {@link Mono} of {@link Object} representing the deserialized {@link BinaryData}. * @throws NullPointerException If {@code typeReference} or {@code serializer} is null. * @see ObjectSerializer * @see JsonSerializer * @see More about serialization */ public Mono toObjectAsync(TypeReference typeReference, ObjectSerializer serializer) { return Mono.fromCallable(() -> toObject(typeReference, serializer)); } /** * Returns an {@link InputStream} representation of this {@link BinaryData}. * *

Get an InputStream from the BinaryData

* * *
     * final byte[] data = "Some Data".getBytes(StandardCharsets.UTF_8);
     * BinaryData binaryData = BinaryData.fromStream(new ByteArrayInputStream(data), (long) data.length);
     * final byte[] bytes = new byte[data.length];
     * binaryData.toStream().read(bytes, 0, data.length);
     * System.out.println(new String(bytes));
     * 
* * * @return An {@link InputStream} representing the {@link BinaryData}. */ public InputStream toStream() { return content.toStream(); } /** * Returns a read-only {@link ByteBuffer} representation of this {@link BinaryData}. *

* Attempting to mutate the returned {@link ByteBuffer} will throw a {@link ReadOnlyBufferException}. * *

Get a read-only ByteBuffer from the BinaryData

* * *
     * final byte[] data = "Some Data".getBytes(StandardCharsets.UTF_8);
     * BinaryData binaryData = BinaryData.fromBytes(data);
     * final byte[] bytes = new byte[data.length];
     * binaryData.toByteBuffer().get(bytes, 0, data.length);
     * System.out.println(new String(bytes));
     * 
* * * @return A read-only {@link ByteBuffer} representing the {@link BinaryData}. */ public ByteBuffer toByteBuffer() { return content.toByteBuffer(); } /** * Returns the content of this {@link BinaryData} instance as a flux of {@link ByteBuffer ByteBuffers}. The content * is not read from the underlying data source until the {@link Flux} is subscribed to. * * @return the content of this {@link BinaryData} instance as a flux of {@link ByteBuffer ByteBuffers}. */ public Flux toFluxByteBuffer() { return content.toFluxByteBuffer(); } /** * Returns the length of the content, if it is known. The length can be {@code null} if the source did not specify * the length or the length cannot be determined without reading the whole content. * * @return the length of the content, if it is known. */ public Long getLength() { return content.getLength(); } /** * Returns a flag indicating whether the content can be repeatedly consumed using all accessors including * {@link #toStream()} and {@link #toFluxByteBuffer()} * *

* Replayability does not imply thread-safety. The caller must not use data accessors simultaneously regardless of * what this method returns. *

* * *
     * BinaryData binaryData = binaryDataProducer();
     *
     * if (!binaryData.isReplayable()) {
     *     binaryData = binaryData.toReplayableBinaryData();
     * }
     *
     * streamConsumer(binaryData.toStream());
     * streamConsumer(binaryData.toStream());
     * 
* * * *
     * Mono.fromCallable(() -> binaryDataProducer())
     *     .flatMap(binaryData -> {
     *         if (binaryData.isReplayable()) {
     *             return Mono.just(binaryData);
     *         } else  {
     *             return binaryData.toReplayableBinaryDataAsync();
     *         }
     *     })
     *     .flatMap(replayableBinaryData ->
     *         fluxConsumer(replayableBinaryData.toFluxByteBuffer())
     *             .then(fluxConsumer(replayableBinaryData.toFluxByteBuffer())))
     *     .subscribe();
     * 
* * * @return a flag indicating whether the content can be repeatedly consumed using all accessors. */ public boolean isReplayable() { return content.isReplayable(); } /** * Converts the {@link BinaryData} into a {@link BinaryData} that is replayable, i.e. content can be consumed * repeatedly using all accessors including {@link #toStream()} and {@link #toFluxByteBuffer()} * *

* A {@link BinaryData} that is already replayable is returned as is. Otherwise techniques like marking and * resetting a stream or buffering in memory are employed to assure replayability. *

* *

* Replayability does not imply thread-safety. The caller must not use data accessors of returned {@link BinaryData} * simultaneously. *

* * *
     * BinaryData binaryData = binaryDataProducer();
     *
     * if (!binaryData.isReplayable()) {
     *     binaryData = binaryData.toReplayableBinaryData();
     * }
     *
     * streamConsumer(binaryData.toStream());
     * streamConsumer(binaryData.toStream());
     * 
* * * @return Replayable {@link BinaryData}. */ public BinaryData toReplayableBinaryData() { if (this.isReplayable()) { return this; } else { return new BinaryData(content.toReplayableContent()); } } /** * Converts the {@link BinaryData} into a {@link BinaryData} that is replayable, i.e. content can be consumed * repeatedly using all accessors including {@link #toStream()} and {@link #toFluxByteBuffer()} * *

* A {@link BinaryData} that is already replayable is returned as is. Otherwise techniques like marking and * resetting a stream or buffering in memory are employed to assure replayability. *

* *

* Replayability does not imply thread-safety. The caller must not use data accessors of returned {@link BinaryData} * simultaneously. *

* * *
     * Mono.fromCallable(() -> binaryDataProducer())
     *     .flatMap(binaryData -> {
     *         if (binaryData.isReplayable()) {
     *             return Mono.just(binaryData);
     *         } else  {
     *             return binaryData.toReplayableBinaryDataAsync();
     *         }
     *     })
     *     .flatMap(replayableBinaryData ->
     *         fluxConsumer(replayableBinaryData.toFluxByteBuffer())
     *             .then(fluxConsumer(replayableBinaryData.toFluxByteBuffer())))
     *     .subscribe();
     * 
* * * @return A {@link Mono} of {@link BinaryData} representing the replayable {@link BinaryData}. */ public Mono toReplayableBinaryDataAsync() { if (isReplayable()) { return Mono.just(this); } else { return content.toReplayableContentAsync().map(BinaryData::new); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy