Current Page: NeXtMidas Training File Handlers Lab 1 Part 1
- - - | Getting started: For this lab, we will start with a template file. Save it as `OrangeFile.java` in the `lib` area of the TRAIN option tree. OrangeFile.java This template has an outline for the file and has the two constructors filled in. Most file handlers have these same constructors in them. Note that the template also has a variable (`header`) and two constants (`HEADER_SIZE` and `BPE`) defined. We will use these shortly. Part 1 - The File Header: Here we will handle reading/writing the file header. Load the header `BaseFile` provides the basic `init(..)` and `open()` methods. As part of `open()`, `BaseFile` calls `setInternals()`. The `setInternals()` is intended to read the header (input files only) and initialize any internal or header information. Since we are likely to access the header often, it is useful to just read the header into memory and work with it there rather than frequently going back to disk to access it (the `header` variable is for holding the header once we've read it in). As part of opening the file `BaseFile` calls `setInternals()`, this sets any "internal" information and initializes the header. For this class, we need a relatively simple method:
            protected void setInternals () {
              if (header == null) {                       // 1
                initHeader();                             // 2
              }                                           // 3
              if ((flags & APPEND) != 0) seek(getSize()); // 4
              else                       seek(0.0);       // 5
            }
    - Line 1: `BaseFile` will call this method twice if file qualifiers were specified. The first call is intended to initialize the header, the second make any updates necessary following the qualifiers. Line 2: The first time this method is called we want to initialize the header. We will have a separate method `initHeader()` for this. Lines 4-5: We need to set the seek pointer (more about this later) to start at either the beginning or the end of the data portion of the file. Next we need to implement the `initHeader()` method.
            private void initHeader () {
              if (isInput) {
                // your code goes here
              }
              else {
                // your code goes here
              }
            }
    - If this is an input file (or an in/out file) we want to read the header of the existing file. `BaseFile` provides an `isInput` variable that indicates if the file is opened for input (there is also a corresponding `isOutput` variable, in the case of an in/out file, both `isInput` and `isOutput` are `true`). We start by setting `header` to a new `byte[]` buffer of length `HEADER_SIZE`. We then need to read the header from the disk. `BaseFile` provides us a handle to the applicable I/O resource called `io` (see the API for `IOResource` for details on the methods it provides). To read the header in we want to use one of `read(..)` methods (note that the buffer offset is 0 since we want to start reading into the start of the header buffer, and then the file offset is 0 since the header is at the very start of the file). If this is only for output to initialize a default header for the file. We start by setting `header` to a new `byte[]` buffer of length `HEADER_SIZE`. We then need to set default header values. We will fill this in shortly, just leave some blank lines here for now. The last thing we need to do in `setInternals(..)` is set the seek pointer to point to the start of the data. We simply to this with the following line:
            seek(offset);
  - - Writing the header `BaseFile` provides the basic `close()` method. As part of `close()`, `BaseFile` calls `update()` to update the file header on disk. Again, the signature must match the signature specified in `BaseFile`.
            public void update () {

            }
All we need to do here is write the header out using one of `write(..)` methods in the I/O resource. continued on next page