Access Segment Of Input

Examples for reading sections of an Input object without reading all data in the underlying resource

IE skip bytes and prematurely close resource.

Skipping Bytes

How to skip the first X bytes.
    import scalax.io._

    val in:Input = Resource.fromURLString("file://someFile")

    // Skip the first 10 bytes.  If underlying resource supports it the
    // bytes will not be read
    // Remember resource is lazy as of assignment resource has not yet been opened
    val restOfBytes = in.bytes.drop(10)

    // After assignment of ''string'' the resource has been opened and processed
    val string = new String(restOfBytes.toArray)
  

Taking Bytes

How to close resource after reading first X bytes
    import scalax.io._

    val in:Input = Resource.fromURLString("file://someFile")

    // Take first 10 bytes then close resource.
    // Remember the resource is lazy so firstTenBytes is not
    // an in-memory collection and accessing it will open
    // the resource and read the data.  At the moment of
    // ''firstTenBytes'' the resource has not been opened.
    val firstTen = in.bytesAsInts.take(10)

    // This statement will open resource take first 10 bytes add
    // them together and close resource.
    val sum = firstTen.reduceLeft(_ + _)
  

Take While

How to take bytes until a condition is met and then close resource

    import scalax.io._

    val in:Input = Resource.fromURLString("file://someFile")

    // take bytes until they one is greater than 5
    // Note: bytes is a view which means it does not open the
    // resource until the actual data is requested.
    // The following statement does not access resource
    val lessThan5 = in.bytesAsInts.takeWhile(_ < 5)


    // This statement will open resource take add
    // bytes together (until a byte greater than 5)
    // and close resource.
    val sum = lessThan5.reduceLeft(_ + _)
  

Limited Fold

Demonstrate the limited/controlled fold of LongTraversable.

The limitFold method allows one to fold over a LongTraversable but terminate the traversal at any arbitrary point. This is not as powerful as the Iteree pattern but is easy to get into if one is familiar with fold


    import scalax.io._

    val in:Input = Resource.fromURLString("file://someFile")

    // add bytes until the fifth encounter of a 5 occurs
    val (fives, sum) = in.bytes.limitFold((0,0)) {
      // By returning End the traversal will stop and the resource closed
      case ((5,sum), 5) => End((5, sum))
      // by returning Continue the traversal will continue
      case ((fives,sum), 5) => Continue((fives + 1, sum + 5))
      // by returning Continue the traversal will continue
      case ((fives,sum), next) => Continue((fives, sum + next))
    }
  

Putting It Together

An example with drop take and limitFold.

    import scalax.io._

    val in:Input = Resource.fromURLString("file://someFile")

    /**
     * Skip first 10 bytes and sum a random number of bytes up
     * to 20 bytes
     */
    in.bytes.drop(10).take(20).limitFold(10) {
      case (acc, next) if util.Random.nextBoolean => End(acc + next)
      case (acc, next) => End(acc + next)
    }