Personal C Sharp         by    famsoft.org

Home | Demonstrative Examples | PC# Methods | PC# Reference | Links

Filing

                                                                           You are welcomed to use our site for your web search.
                                                                    See the fine products advertised at the bottom of each page too.

                                 DEMONSTRATIVE EXAMPLES
                                 ======================

                                   EXAMPLES ON FILING
                                   ===================


For many years, filing has been easy and simple. There has been two types of files:

(1) Sequencial Access Files (SAF)'s: In this type records are read sequencially, so you
can't read a record unless you read all the records located before it in the file.

(2) Random Access Files (RAF)'s: In which you can read a record located at any place
in the file instantly by supplying its record number.

Sequencial Access Files have been good for short files, like "letters" and "memos".
Random Access Files have been good for longer files like "Inventories" and "Personell"
files.

Things have become more complicated recently, SAF's have become not as easy to create and
RAF's have been replaced with databases. This is fine for a large business but not as
good for someone who likes to use his programming ability to put his personal data into
a file made to his/her specs.

Personal C# is specialized in simplification, so we have developed a software which returns
you to the good old days. Both file types are now available and their creation and use
have become even simpler.

SELECTING THE FILE KEYNAME:  If you have already looked at the examples on "Controls", you
know what keynames mean. You know that the keyname "bt0" represents a button since the
first two characters "bt" are for a Button type. You also know that you should supply
(cs="bt0") when you call method cm() at any mode to perform an operation on that button.

In Filing, we have only two types of files SAF and RAF. The two char's representing each
of them are "sf" and "rf" respectively. So, you can name your first SAF "sf0" and you
should supply (fs="sf0") when you call method fm() at any mode to perform an operation on
that file.

Filing keynames can also be either 3 or 4 characters long, just like Control's keynames.
So "sf0", "rf08"and "sf89" are all legal keynames. you cannot use numbers which start with
9 since they are reserved for internal use. So "sf9" and "rf90" are illegal keynames.

FILING OBJECTS:

 

=========================================================================================
EXAMPLE 1: Make a short text file using Notepad and save it under the name "test.txt".
We are going to Read the file and display its contents on the "Text Screen".

We are going to use 2 file read modes "read all" to read it all at once and "read line"
to read it line by line.
=========================================================================================
public class a:pcs {
  public override void init() {
    tia=toa="t";                         // Select "text screen" display
    bli=1;                               // Start execution at block 1
    base.init();                         // Initialize PC# classes
  }
  public override void run() {
    if (blp==1) {                        // Starting block
      os="Using Read All mode: ";tm();   // First mode
      fls="test.txt";fs="sf0";fm("or");  // Open for read, use keyname "sf0"
      fm("ra");tm();                     // Read it all & display it
      fm("c");                           // Close file

      os="\nUsing Read Line mode: ";tm();// Second mode.
      fls="test.txt";fs="sf0";fm("or");  // Open for read, use keyname "sf0"
      dnb=false;                         // Initialize End Of File flag
      while (!dnb) {
        fm("rl");if (!dnb) tm();         // Keep reading lines until EOF
      }
      fm("c");                           // Close file
    }   
  }
}
=========================================================================================
HOW TO WRITE, COMPILE AND RUN THE PROGRAM? See Example 1 of the "General Examples".
=========================================================================================
TUTORIAL: Reading a SAF is very easy. At first, we select a keyname for it. Since it is
a SAF the keyname must start with "sf". We called it "sf0" since it is the first file.

The second step is to open the file. There are 3 modes to open a SAF at:

or  Open for read, which is the mode we wanted.
ow  Open for write
oa  Open for append

There are also 3 modes for reading a SAF:

ra  Read the entire file and assign its text content to (os)
rl  Read one line
rb  Read one byte

The boolean var (dnb) which is the "done" flag is a general flag used to indicate whether
something we are working on has been completed or not. In filing, dnb changes its state to
true when an end of file (EOF) has been encountered.

So, before we start reading, we make sure that it is (false) then we keep reading until it
changes to (true)

You may have noticed that we has specified the file keyname only when we opened it, we
didn't specify it when we read the file text or when we closed it. Why?. The answer is
that method fm() does not reset (fs) at its end like it resets the GUV's. So we have been
able to get away with doing that. However, this is not a good practice. If we have been
working with more than one file, we should have specified the file keyname at each
operation.
=========================================================================================

demo35.jpg

Example 1: Reading SAF using two modes, read all and read line.
You may download the executable file for Example 1 at: http://mysite.verizon.net/vze1l4h6/examples/F1.exe

EXAMPLE 2: This time, we are not going to write a full class for each example, we are
going to add one block for each new example to the class of example 1. so, this example
will be in block 2. After adding block two to the last class, change the startup block
request statement in method init() to (bli=2;)

In this example, we are going to erase "test.txt" file contents, open it in "write" mode,
write the line "Text Line Number 1" into it, close it then open it again in "append" mode,
write the line "Text Line Number 2" into it, close it then open it in "read" mode, read
and display all its data.
=========================================================================================

    if (blp==2) {
     // ----------------------- CREATING THE FILE AND WRITING DATA ---------------------
      ks="f";fls="test.txt";fm("D");    // delete file.
      fls="test.txt";fs="sf0";fm("ow"); // open for write
      os="Text Line Number 1";fm("wl"); // write line
      fm("c");                          // close
      os="Data written to file";tm();   // Inform user
      fls="test.txt";fs="sf0";fm("oa"); // open for append
      os="Text Line Number 2";fm("wl"); // write line
      fm("c");                          // close
      os="Data appended to fle";tm();// Inform user
     // --------------------------------- READING DATA BACK ----------------------------
      os="Reading data back:";tm();
      fls="test.txt";fs="sf0";fm("or"); // Open for read
      fm("ra");tm();                    // Read all file & display on text screen
      fm("c");                          // close
    }
=========================================================================================

demo36.jpg

Example 2: Shows how to write text to a file, append to it then read all its contents.
You may download the executable file for Example 2 at: http://mysite.verizon.net/vze1l4h6/examples/F2.exe

EXAMPLE 3: Now, we need to add a new block to show how to obtain current directory name,
            how to check if a file or dir exists, how to create files and dir's and delete
            them, how to get a list of all files & sub folders in a folder and how to
            copy one file to another.
 
            So. add block 3 to your program and change "Startup block request" statement
            in method init() to (bli=3;)
=========================================================================================
    if (blp==3) {
      //-------------- OBTAINING CURRENT DIRECTORY AND CHECKING ATTRIBUTES --------------
      fm(".");os="Current Directory: "+os;tm();    // Get currnt dir name, dsplay it.
      fls="x.txt";fm("A");os="Code: "+os;tm();     // Get attributes & dsplys returned
      fls="xxxx.cs";fm("A");os="Code: "+os;tm();   // code for 3 items. Should display "f"
      fls="c:\\health";fm("A");os="Code: "+os;tm();// if file, "d" if directory, " " if
                                                   // non-existing.
 
      //------------------ CREATING AND DELETING FILES AND DIRECTORIES ------------------
      ks="f";fls="testFl";fm("M");os="File created";tm();// Create file, inform user.
      ks="f";fls="testFl";fm("D");os="File deleted";tm();// Delete same file
      ks="d";fls="testDir";fm("M");os="Dir created";tm();// Create dir, inform user
      ks="d";fls="testDir";fm("D");os="Dir deleted";tm();// Delete same dir
 
      //----------- DISPLAYING ALL SUB-FOLDERS AND FILE CONTENTS OF A FOLDER -----------
      os="Reading file list:";tm();
      ks="d";fls="c:\\cs";fm("L");                   // Get all sub-dir's in OS[]
      om("fa");                                      // Convert OS[] to (os)
      ns=os;                                         // save (os) temporarely in (ns)
      ks="f";fls="c:\\cs";fm("L");                   // Get all files in OS[]
      om("fa");                                      // Convert to (os)
      os=ns+os;tm();                                 // Add the 2 lists & display
 
      //-------------------------- COPYING FILES AND DIRECTORIES ------------------------
      fls="c:\\JS\\temp.txt";os="newfile.txt";fm("C");// copy extrnl fle to local fle
      os="File copied";tm();                          // Inform user with dialog box
      ks="f";fls="newfile.txt";fm("D");               // Delete new file
      os="File deleted";tm();                         // Inform user
    }
=========================================================================================
TUTORIAL: So far everything seems to be too easy to require additional explanation. Let
us now get into the more important filing type "The Random Access Filing".
 

                                 RANDOM ACCESS FILES
                                 ===================
The difference between a SAF and RAF is in the record length.
 
In a text SAF, the strings you write into the file are not of equal lengthes, the only
way we can seperate them from each other is by adding a "new line" code at the end of
each string. The new line code which we use is made of two special characters, a carriage
return character (code 13 in decimal form) followed with a line feed character (code 10,
decimal)
 
In a RAF, you specify a record length when you open the file. The record length you choose
should be at least equal to the length of the longest string which you may like to add to
the file. When you call method fm() with a string which you want to write into the file,
the method adds at the end of your string as many null characters as it takes to make its
length equal to the record length.
 
Since all records of a RAF are of same length, it is possible to know where the start and
end of any record in the file are, so we can retrieve the record instantly without having
to read all the records which preceed it into the file.
 
We have two types of RAF's:
 
(1) Manually read RAF's.
(2) Automatically read RAF's
 
In the first type, you need to supply the record length each time you open the file and
you are on your own concerning how you place your data into your record.
 
In the second type, at the time you create the file, you supply the filing method fm()
with the record length and data concerning the fields each record should contain. After
the file is created, the method writes a header record at the beginning of the file
which contains all data necessary to read its records and to retrieve the field data
within them. So anytime you open the file for read or write thereafter, you don't have
to tell the method how to read it or where fields are located.
 
Next example will be on the first type of Random Access Files.
=========================================================================================

demo37.jpg

Example 3: Shows how to create, delete, copy and check attributes of files.
Also shows how to get current directory and to list the contents of a directory.
You may download the executable file for Example 3 at: http://mysite.verizon.net/vze1l4h6/examples/F3.exe

EXAMPLE 4: We are going to add a new block to last program to show how to write 2 lines
           into a no header Random Access File (RAF) then read them back. We need to
           erase file contents before writing into it.
=========================================================================================
    // ----------------------- CREATING THE FILE AND WRITING DATA ---------------------
    if (blp==4) {
      fls="test.raf";fm("A");              // check file attributes
      if(os != " ") {ks="f";fm("D");}      // If exists, delete it
      fls="test.raf";fs="rf0";rcl=24;ib=true;fm("o");
                                           // open RAF, record len=24,no header
      rcs="Line number one.";rci=0;fm("w");// Write first record
      rcs="Line #2.";rci=1;fm("w");        // Write second record
      fm("c");                             // Close the file.
      // --------------------------------- READING DATA BACK ----------------------------
      fls="test.raf";fs="rf0";rcl=24;ib=true;fm("o");
                                           // open RAF again
      n=0;dnb=false;                       // Initialize record number counter, eof flag.
      while (!dnb) {                       // Start record reading loop.
        rci=n;fm("r");                     // Read one record.
        os=rcs;om("c");                    // Clean record (remove trailing null chars)
        tm();                              // Then display record.
        n++;                               // increment record number.
      }
      fm("c");                             // Close the file.
    }
=========================================================================================
TUTORIAL: As you can see, the records supplied to method fm() to be written into the file
have not been equal in length, but the method made them equal by adding enough null
char's to each of them to make the length of each one of them equal to the record length.
 
When the records were read back, they came with the null char's attached to them, so we
had to remove the null chars before displaying them.
 
HOW TO CREATE AN AUTOMATICALLY READ RAF:
 
The first step is to create the header. To do so, you open the file as a no header file,
write the header then close it.
 
To create the header, you need to determine the fields necessary. To simplify things, we
use only two types of fields, string and numeric fields. A numeric field always occupies
5 bytes. The number of bytes a string field requires is the number of characters of the
logest string to be writen into it.
 
Setting the record length:
 
To calculate the record length, add the bytes which all fields require together, then add
some more spare bytes for future expansion.
 
Setting the data type:
 
The double type var (od) is used to indicate the data type for a field. Here is how to
detrmine data types:
 
(1) For a string field, od=No. of characters occupied by the field.
(2) For a numeric field, (od) is always in the range (0.0 to 0.9) The number to the right
    of the decimal point is the number of decimal digits you like the field to have.
    If the field will be used to represent money, you would be expected to choose (od=0.2)
    so your numbers come formatted as Dollars and Cents. If the field is going to be used
    to store an integer, you would use (od=0.0) since there will be no decimal digits.
 
So, (od) can tell exactly what a field contains. If it was an integer like (35), we know
that the field is a string, upto 35 characters long. If it was zero (0.0), the field
is an integer and if it was a fraction like (0.4) we know that the field is a number of
4 decimal digits (in this case)
 
How the header data is supplied:
 
Practically, we don't supply field data one at a time, we supply them all at once. We
supply the array OS[] containing all field names, and array OD[] containing all field
types in the same order at which we like the fields to be placed into the record.
=========================================================================================

demo38.jpg

Example 4: Shows how to write two lines into a Random Access file (RAF) and read them back.
You may download the executable file for Example 4 at: http://mysite.verizon.net/vze1l4h6/examples/F4.exe

EXAMPLE 5:  Let us add a new block to last program to show how to make a RAF with a
            header containing all information necessary for reading it. We are also going
            to Enter two records of data into the file then read them back and display
            them on the screen.
=========================================================================================
    if (blp==5) {
      // ------------------- CREATING THE FILE AND WRITING THE HEADER ------------------
      fls="test.raf";fm("A");              // check file attributes
      if(os != " ") {ks="f";fm("D");}      // If exists, delete it
      fs="rf0";rcl=100;ib=true;fm("o");    // open the file as no header file
      OS[0]="name";OD[0]=35;               // 35 character string field
      OS[1]="age";OD[1]=0.0;               // Integer field
      OS[2]="position";OD[2]=25;           // 25 character string field
      OS[3]="salary";OD[3]=0.2;            // numeric field with 2-decimal digits
      fm("wh");                            // Write header.
      fm("c");                             // Close the file.
      // -------------------------- ENTERING DATA INTO THE FILE -------------------------
      fls="test.raf";fs="rf0";fm("o");     // open file and read header information
                                           // Notice that we did not supply rec#
      OS[0]="John Smith";                  // First field data, a string in OS[]
      OD[1]=25;                            // Second field data, a number in OD[]
      OS[2]="Machine operator";            // Third field data, a string in OS[]
      OD[3]=35000.50;                      // Fourth field data, a number in OD[]
      rci=1;fm("w");                       // Write record #1
      OS[0]="Mary Jones";                  //
      OD[1]=20;                            //
      OS[2]="Clerk";                       // Field data for second record
      OD[3]=25000.66;                      //
      rci=2;fm("w");                       // Write record #2
      fm("c");                             // Close the file.
      // ------------------------------ READING DATA BACK ------------------------------
      fls="test.raf";fs="rf0";fm("o");     // open file and read header information
                                           // Notice that we did not supply rec# or any
                                           // field information. The file reads itself.
      n=1;                                 // Start by record # 1
      while (!dnb) {                       // Do until eof encountered.
        rci=n;fm("r");                     // Read one record. (See REMARK)
        os=OS[0];tm();                     // Read and display 1st field
        os=OS[1];tm();                     // Read & display 2nd field
        os=OS[2];tm();                     // Read and display 3rd field
        os=OS[3];tm();                     // Read & display 4th field
        os="";tm();                        // Add blank line to seperate records
        n++;                               // increment record number.
      }
      fm("c");                             // Close the file.
    }
=========================================================================================
TUTORIAL: As you can see, at the block of code titeled "CREATING THE FILE AND WRITING THE
HEADER", the file did not have a header, so we opened it as a no header RAF. We wrote the
header and closed the file. From this point up, the file is a self read file, reading it
or writing into it does not require supplying any information other than the file name.
At the block of code titled "ENTERING DATA INTO THE FILE", we opened the file as a RAF
with a header (since ib=false), so we did not need to supply rec length. Immediately
after the open statement, we have all field names in OS[] and their type codes in OD[]
If you have forgot what was in the file you can remind yourself by displaying the two
arrays with a code like this:
fls="test.raf";fs="rf0";fm("o");         // open file and read header info;
fm("rh");                                // Read header
for (c=0;c<20;c++) {                     // Scan field arrays
  if (OS[c].Length<1) break;             // Stop at end of data
  os="Name: "+OS[c]+" Type: "+OD[c];tm();// Display name and type of each field
}
This is what you get:
Name: name      Type: 35
Name: age       Type: 0
Name: position  Type: 25
Name: salary    Type: 0.2
You may be wondering why we included the read header statement [fm("rh")] if the open
statement have already read the header. The answer is that the open statement reads the
header, copies OS[] and OD[] contents to internal PC# archives then resets OS[] and OD[]
so they can be used in the next record read or write operations.
READING AND WRITING DATA:
You must have noticed that we leave empty gaps into arrays OS[] and OD[] when we read
or write. For example, during writing of the first 3 fields, we skipped
      OS[0]="John Smith";                  // First field data, a string in OS[]
      OD[1]=25;                            // Second field data, a number in OD[]
      OS[2]="Machine operator";            // Third field data, a string in OS[]
OD[0],OS[1] and OD[2]. The rule is that when the field is string, we keep its place in
OD[] empty and when the field is numeric we keep its place in OS[] empty. Why do we need
these gaps? In addition to simplicity, After each read operation, numeric field data are
formatted according to their type specs and their string type format is stored into its
place in OS[] in addition to their numeric value which is stored in OD[].
=========================================================================================

demo39.jpg

Example 5: Shows how to write the header of a RAF, write two records of data into it then read them back.
You may download the executable file for Example 5 at: http://mysite.verizon.net/vze1l4h6/examples/F5.exe