Skip to content

LargeFileTaskUpload's constructor checks for available bytes (it should not) #1621

@kekolab

Description

@kekolab

When creating a LargeFileTaskUpload, the constructor checks whether the stream has available bytes or not

, but, the javadoc of InputStream.available() clearly states that:

Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking, which may be 0, or 0 when end of stream is detected [...] Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.

While it is true that, in LargeFileUploadTask's constructor, it is not used to allocate a buffer, when available() returns 0, an exception is raised and the stream cannot be used (although it contains bytes).

The funny side is that when called of a stream returned by the SDK, available() returns 0!!! So, and it is a paradox, the stream of a file returned by the API cannot be used in the API itself to upload its content to another location and/or drive.

I am using version 3.1.10

Expected behavior

You should be able to construct a LargeFileUploadTask also when InputStream.available() returns 0.

Actual behavior

You cannot construct a LargeFileUploadTask also when InputStream.available() returns 0.

Steps to reproduce the behavior

The stream returned by the SDK itself reports 0 bytes available

The following test fails

    @Test
    public void bug_NoBytesAvailables() throws IOException {
        GraphServiceClient client = // obtain it somehow
        Drive drive = client.me().drive().get();
        DriveItem root = client.drives().byDriveId(drive.getId()).root().get();
        DriveItem file = client.drives().byDriveId(drive.getId()).items()
                .byDriveItemId(root.getId()).children().get().getValue().stream()
                .filter(child -> child.getFile() != null).findAny().get();
        InputStream fileContent = client.drives().byDriveId(drive.getId()).items()
                .byDriveItemId(file.getId()).content().get();
        assertTrue(fileContent.available() > 0);
    }

The stream returned by the SDK actually has available bytes

Same code, but I do not call the available method and read the stream. This test passes

    @Test
    public void bug_BytesAreActuallyThere() throws IOException {
        GraphServiceClient client = // obtain it somehow
        Drive drive = client.me().drive().get();
        DriveItem root = client.drives().byDriveId(drive.getId()).root().get();
        DriveItem file = client.drives().byDriveId(drive.getId()).items()
                .byDriveItemId(root.getId()).children().get().getValue().stream()
                .filter(child -> child.getFile() != null).findAny().get();
        InputStream fileContent = client.drives().byDriveId(drive.getId()).items()
                .byDriveItemId(file.getId()).content().get();
        byte[] content = fileContent.readAllBytes();
        assertTrue(content.length > 0);
    }

Conclusions

A stream returned by the SDK itself cannot be used to create a LargeFileUploadTask.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions