예제 #1
0
    public void FileBufferingReadStream_SyncReadUnderThreshold_DoesntCreateFile()
    {
        var inner = MakeStream(1024 * 2);

        using (var stream = new FileBufferingReadStream(inner, 1024 * 3, null, Directory.GetCurrentDirectory()))
        {
            var bytes = new byte[1000];
            var read0 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(bytes.Length, read0);
            Assert.Equal(read0, stream.Length);
            Assert.Equal(read0, stream.Position);
            Assert.True(stream.InMemory);
            Assert.Null(stream.TempFileName);

            var read1 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(bytes.Length, read1);
            Assert.Equal(read0 + read1, stream.Length);
            Assert.Equal(read0 + read1, stream.Position);
            Assert.True(stream.InMemory);
            Assert.Null(stream.TempFileName);

            var read2 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(inner.Length - read0 - read1, read2);
            Assert.Equal(read0 + read1 + read2, stream.Length);
            Assert.Equal(read0 + read1 + read2, stream.Position);
            Assert.True(stream.InMemory);
            Assert.Null(stream.TempFileName);

            var read3 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(0, read3);
        }
    }
예제 #2
0
    public void FileBufferingReadStream_UsingMemoryStream_RentsAndReturnsRentedBuffer_WhenCopyingFromMemoryStreamDuringRead()
    {
        var    inner = MakeStream(1024 * 1024 + 25);
        string tempFileName;
        var    arrayPool = new Mock <ArrayPool <byte> >();

        arrayPool.Setup(p => p.Rent(It.IsAny <int>()))
        .Returns((int m) => ArrayPool <byte> .Shared.Rent(m));
        arrayPool.Setup(p => p.Return(It.IsAny <byte[]>(), It.IsAny <bool>()))
        .Callback((byte[] bytes, bool clear) => ArrayPool <byte> .Shared.Return(bytes, clear));

        using (var stream = new FileBufferingReadStream(inner, 1024 * 1024 + 1, 2 * 1024 * 1024, GetCurrentDirectory(), arrayPool.Object))
        {
            arrayPool.Verify(v => v.Rent(It.IsAny <int>()), Times.Never());

            stream.Read(new byte[1024 * 1024]);
            Assert.False(File.Exists(stream.TempFileName), "tempFile should not be created as yet");

            stream.Read(new byte[4]);
            Assert.True(File.Exists(stream.TempFileName), "tempFile should be created");
            tempFileName = stream.TempFileName !;

            arrayPool.Verify(v => v.Rent(It.IsAny <int>()), Times.Once());
            arrayPool.Verify(v => v.Return(It.IsAny <byte[]>(), It.IsAny <bool>()), Times.Once());
        }

        Assert.False(File.Exists(tempFileName));
    }
예제 #3
0
    public void FileBufferingReadStream_SyncReadWithOnDiskLimit_EnforcesLimit()
    {
        var    inner = MakeStream(1024 * 2);
        string tempFileName;

        using (var stream = new FileBufferingReadStream(inner, 512, 1024, GetCurrentDirectory()))
        {
            var bytes = new byte[500];
            var read0 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(bytes.Length, read0);
            Assert.Equal(read0, stream.Length);
            Assert.Equal(read0, stream.Position);
            Assert.True(stream.InMemory);
            Assert.Null(stream.TempFileName);

            var read1 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(bytes.Length, read1);
            Assert.Equal(read0 + read1, stream.Length);
            Assert.Equal(read0 + read1, stream.Position);
            Assert.False(stream.InMemory);
            Assert.NotNull(stream.TempFileName);
            tempFileName = stream.TempFileName !;
            Assert.True(File.Exists(tempFileName));

            var exception = Assert.Throws <IOException>(() => stream.Read(bytes, 0, bytes.Length));
            Assert.Equal("Buffer limit exceeded.", exception.Message);
            Assert.False(stream.InMemory);
            Assert.NotNull(stream.TempFileName);
        }

        Assert.False(File.Exists(tempFileName));
    }
예제 #4
0
    private static async ValueTask <byte[]> ReadDataAsync(JsonTranscodingServerCallContext serverCallContext)
    {
        // Buffer to disk if content is larger than 30Kb.
        // Based on value in XmlSerializer and NewtonsoftJson input formatters.
        const int DefaultMemoryThreshold = 1024 * 30;

        var memoryThreshold = DefaultMemoryThreshold;
        var contentLength   = serverCallContext.HttpContext.Request.ContentLength.GetValueOrDefault();

        if (contentLength > 0 && contentLength < memoryThreshold)
        {
            // If the Content-Length is known and is smaller than the default buffer size, use it.
            memoryThreshold = (int)contentLength;
        }

        using var fs = new FileBufferingReadStream(serverCallContext.HttpContext.Request.Body, memoryThreshold);

        // Read the request body into buffer.
        // No explicit cancellation token. Request body uses underlying request aborted token.
        await fs.DrainAsync(CancellationToken.None);

        fs.Seek(0, SeekOrigin.Begin);

        var data = new byte[fs.Length];
        var read = fs.Read(data);

        Debug.Assert(read == data.Length);

        return(data);
    }
예제 #5
0
    public void PartialReadThenSeekReplaysBuffer()
    {
        var data  = Enumerable.Range(0, 1024).Select(b => (byte)b).ToArray();
        var inner = new MemoryStream(data);

        using var stream = new FileBufferingReadStream(inner, 1024 * 1024, bufferLimit: null, GetCurrentDirectory());

        var withoutBufferMs = new MemoryStream();
        var buffer          = new byte[100];
        var read1           = stream.Read(buffer);

        stream.Position = 0;
        var buffer2 = new byte[200];
        var read2   = stream.Read(buffer2);

        Assert.Equal(100, read1);
        Assert.Equal(100, read2);
        Assert.Equal(data.AsMemory(0, read1).ToArray(), buffer);
        Assert.Equal(data.AsMemory(0, read2).ToArray(), buffer2.AsMemory(0, read2).ToArray());
    }
예제 #6
0
    public void FileBufferingReadStream_SyncReadOverThreshold_CreatesFile()
    {
        var    inner = MakeStream(1024 * 2);
        string tempFileName;

        using (var stream = new FileBufferingReadStream(inner, 1024, null, GetCurrentDirectory()))
        {
            var bytes = new byte[1000];
            var read0 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(bytes.Length, read0);
            Assert.Equal(read0, stream.Length);
            Assert.Equal(read0, stream.Position);
            Assert.True(stream.InMemory);
            Assert.Null(stream.TempFileName);

            var read1 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(bytes.Length, read1);
            Assert.Equal(read0 + read1, stream.Length);
            Assert.Equal(read0 + read1, stream.Position);
            Assert.False(stream.InMemory);
            Assert.NotNull(stream.TempFileName);
            tempFileName = stream.TempFileName !;
            Assert.True(File.Exists(tempFileName));

            var read2 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(inner.Length - read0 - read1, read2);
            Assert.Equal(read0 + read1 + read2, stream.Length);
            Assert.Equal(read0 + read1 + read2, stream.Position);
            Assert.False(stream.InMemory);
            Assert.NotNull(stream.TempFileName);
            Assert.True(File.Exists(tempFileName));

            var read3 = stream.Read(bytes, 0, bytes.Length);
            Assert.Equal(0, read3);
        }

        Assert.False(File.Exists(tempFileName));
    }
예제 #7
0
    public async Task ReadThenCopyToAsyncWorks()
    {
        var data  = Enumerable.Range(0, 1024).Select(b => (byte)b).ToArray();
        var inner = new MemoryStream(data);

        using var stream = new FileBufferingReadStream(inner, 1024 * 1024, bufferLimit: null, GetCurrentDirectory());

        var withoutBufferMs = new MemoryStream();
        var buffer          = new byte[100];
        var read            = stream.Read(buffer);
        await stream.CopyToAsync(withoutBufferMs);

        Assert.Equal(100, read);
        Assert.Equal(data.AsMemory(0, read).ToArray(), buffer);
        Assert.Equal(data.AsMemory(read).ToArray(), withoutBufferMs.ToArray());
    }