com.azure.core.util.BinaryData Maven / Gradle / Ivy
Show all versions of azure-core Show documentation
// 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);
}
}
}