public static void ReadLimitLengthStreamWithGrowingFile() { var growingFilename = Path.GetTempFileName(); long fixedGrowingStreamLength, limitStreamLength, nextGrowingStreamLength; using (CancellationTokenSource tokenSource = new CancellationTokenSource()) { Task task = TestUtils.GrowingFile(growingFilename, tokenSource.Token); Thread.Sleep(100); using (FileStream growingStream = new FileStream(growingFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { Thread.Sleep(100); fixedGrowingStreamLength = growingStream.Length; Thread.Sleep(100); using (var limitStream = new ReadLimitLengthStream(growingStream, fixedGrowingStreamLength)) { Thread.Sleep(100); nextGrowingStreamLength = growingStream.Length; limitStreamLength = limitStream.Length; } } } Console.WriteLine($"fixedGrowingStreamLength:{fixedGrowingStreamLength} limitStreamLength:{limitStreamLength} nextGrowingStreamLength:{nextGrowingStreamLength}"); Assert.IsTrue(fixedGrowingStreamLength > 0); Assert.AreEqual(fixedGrowingStreamLength, limitStreamLength); Assert.IsTrue(limitStreamLength < nextGrowingStreamLength); }
public static void ReadLimitLengthStream() { Action <IEnumerable <int>, IEnumerable <byte> > assertArray = (expected, actual) => { List <int> expectedList = expected.ToList(); List <byte> actualList = actual.ToList(); Assert.AreEqual(expectedList.Count, actualList.Count, "Count"); for (int i = 0; i < expectedList.Count; i++) { Assert.AreEqual((byte)expectedList[i], actualList[i], "Index {0}", i); } }; byte[] readBuffer = new byte[10]; Action <Stream, int, int> testSeek = (stream, position, readByte) => { stream.Position = position; Assert.AreEqual(position, stream.Position); Assert.AreEqual(readByte, stream.ReadByte()); Assert.AreEqual(position, stream.Seek(position, SeekOrigin.Begin)); Assert.AreEqual(position, stream.Position); Array.Clear(readBuffer, 0, 10); Assert.AreEqual(readByte >= 0 ? 1 : 0, stream.Read(readBuffer, 1, 1), "Read count"); if (readByte >= 0) { // Make sure nothing was read before or after the offset byte given as well. Assert.AreEqual(readBuffer[0], 0); Assert.AreEqual(readBuffer[1], readByte); Assert.AreEqual(readBuffer[2], 0); } else { // Make sure nothing was read Assert.AreEqual(readBuffer[0], 0); Assert.AreEqual(readBuffer[1], 0); Assert.AreEqual(readBuffer[2], 0); } Assert.AreEqual(position, stream.Seek(position - stream.Length, SeekOrigin.End)); Assert.AreEqual(position, stream.Position); Assert.AreEqual(readByte, stream.ReadByte()); }; // Base stream is a sequence from 0..9 using (MemoryStream baseStream = new MemoryStream(Enumerable.Range(0, 10).Select(i => (byte)i).ToArray())) { using (ReadLimitLengthStream stream = new ReadLimitLengthStream(baseStream, 5)) { Assert.AreEqual(5, stream.Length); // Test reading past array bounds Assert.AreEqual(5, stream.Read(readBuffer, 0, 10), "Read count"); assertArray(Enumerable.Range(0, 5), readBuffer.Take(5)); // Set the position directly and read a shorter range stream.Position = 2; Assert.AreEqual(2, stream.ReadAsync(readBuffer, 0, 2).Await(), "Read count"); assertArray(Enumerable.Range(2, 2), readBuffer.Take(2)); } // Make sure the stream will be seeked if the start does not match the current position. baseStream.Position = 0; using (ReadLimitLengthStream stream = new ReadLimitLengthStream(baseStream, 2, 4)) { // Make sure the position is updated when the stream is created Assert.AreEqual(0, stream.Position); // Test basic read Assert.AreEqual(4, stream.Read(readBuffer, 0, 4), "Read count"); assertArray(Enumerable.Range(2, 4), readBuffer.Take(4)); // Test CopyTo using (MemoryStream destination = new MemoryStream()) { stream.Position = 0; stream.CopyTo(destination); assertArray(Enumerable.Range(2, 4), destination.ToArray()); } // Test CopyToAsync using (MemoryStream destination = new MemoryStream()) { stream.Position = 0; stream.CopyToAsync(destination).Await(); assertArray(Enumerable.Range(2, 4), destination.ToArray()); } // Test seeking testSeek(stream, 0, 2); testSeek(stream, 1, 3); testSeek(stream, 2, 4); testSeek(stream, 3, 5); testSeek(stream, 4, -1); // Test seeking from current stream.Position = 0; Assert.AreEqual(2, stream.Seek(2, SeekOrigin.Current)); Assert.AreEqual(2, stream.Position); // Test clamping of position stream.Position = -2; Assert.AreEqual(0, stream.Position); Assert.AreEqual(2, baseStream.Position); stream.Position = 9; Assert.AreEqual(4, stream.Position); Assert.AreEqual(6, baseStream.Position); // Make sure changing the base stream still shows clamped positions baseStream.Position = 0; Assert.AreEqual(0, stream.Position); baseStream.Position = 4; Assert.AreEqual(2, stream.Position); baseStream.Position = 10; Assert.AreEqual(4, stream.Position); // Reading when the baseStream is positioned before the start of the limit // should still be possible, and should seek to return the correct values. baseStream.Position = 0; Assert.AreEqual(0, stream.Position); Assert.AreEqual(2, stream.ReadByte()); } // Check a stream with length 0 baseStream.Position = 0; using (ReadLimitLengthStream stream = new ReadLimitLengthStream(baseStream, 2, 0)) { // Make sure the position is updated when the stream is created Assert.AreEqual(0, stream.Position); // Test basic read Assert.AreEqual(0, stream.Read(readBuffer, 0, 4), "Read count"); // Test seeking testSeek(stream, 0, -1); testSeek(stream, 0, -1); // Test seeking from current stream.Position = 0; Assert.AreEqual(0, stream.Seek(2, SeekOrigin.Current)); Assert.AreEqual(0, stream.Position); // Test clamping of position stream.Position = -2; Assert.AreEqual(0, stream.Position); Assert.AreEqual(2, baseStream.Position); stream.Position = 9; Assert.AreEqual(0, stream.Position); Assert.AreEqual(2, baseStream.Position); // Make sure changing the base stream still shows clamped positions baseStream.Position = 0; Assert.AreEqual(0, stream.Position); baseStream.Position = 4; Assert.AreEqual(0, stream.Position); baseStream.Position = 10; Assert.AreEqual(0, stream.Position); } } }