Accessing the Filesystem

Introduction


This tutorial demonstrates some of the filesystem operations available to Neko programs. The neko.FileSystem class contains most of the methods we will use.

Pre/Post Conditions


The example uses an existing text file. Before running the program, create a file in the current directory. It can contain anything or can be empty. If it's not named "input.txt," pass its name to the program on the command line.

When the program completes there will be a subdirectory in the current directory named "subdir" which contains a copy of the input file. The filename of the copy will be the name of the input file with "renamed_" prepended to it.

Walkthrough


In this example, we will:
- check that the input file exists
- query the system for the file's access time, size, etc.
- check if a directory exists.
- create a subdirectory
- make two copies of the input file in the subdirectory
- rename one of the copies
- make a directory listing of the subdirectory
- delete one of the copies in the subdirectory

Notes


At each step, we check to see if input files exist before they are read. We also check if output files exist after they've been written. If a file is expected and not found, the program reports the error and exits.

The following statements both return true if dirname is the name of an existing directory:
- neko.FileSystem.isDirectory(dirname)
- neko.FileSystem.kind(dirname) == neko.FileKind.kdir

There is no "path.join" method. Instead, just make a string using either / or \ as the directory separator.

Running the program a second time will not give the same output since the subdirectory and renamed file will already exist. Repeated runs will satisfy the post-conditions stated above, though.

The Code

import neko.FileSystem;
import neko.Sys;
import neko.io.File;

class FileSystemExample
{
  static function main()
  {
    // get filename from command line arg, or use "input.txt" if no arg specified
    var fname = (neko.Sys.args().length==0) ? "input.txt" : neko.Sys.args()[0];

    // check that file exists
    if( neko.FileSystem.exists(fname) )
      neko.Lib.println("file exists");
    else
    {
      neko.Lib.println("file not found");
      neko.Sys.exit(1); // quit
    }

    // get absolute path
    neko.Lib.println("filename: " + neko.FileSystem.fullPath(fname));

    // check file attributes
    var stat:FileStat = neko.FileSystem.stat(fname);
    neko.Lib.println("Last access time: " + stat.atime);
    neko.Lib.println("Last modification time: " + stat.mtime);
    neko.Lib.println("Last status change time: " + stat.ctime);

    // create a subdirectory if it doesn't already exist
    var dirname = "subdir";
    if( !neko.FileSystem.exists(dirname) )
    {
      neko.FileSystem.createDirectory(dirname);

      // check that it was successfull
      if( neko.FileSystem.exists(dirname) && neko.FileSystem.isDirectory(dirname)
      && neko.FileSystem.kind(dirname) == neko.FileKind.kdir )
    neko.Lib.println("subdirectory " + dirname + " was created");
      else
      {
    neko.Lib.println("subdirectory creation failed");
    neko.Sys.exit(1); // quit
      }
    }
    else
    neko.Lib.println("subdirectory already existed");

    // put two copies of the file into the new subdirectory
    neko.io.File.copy(fname, dirname + "/" + fname);
    neko.io.File.copy(fname, dirname + "/duplicate_" + fname);

    // check that new files exist
    if( neko.FileSystem.exists(dirname + "/" + fname) &&
    neko.FileSystem.exists(dirname + "/duplicate_" + fname) )
      neko.Lib.println("copy successfull");
    else
    {
      neko.Lib.println("copy failed");
      neko.Sys.exit(1); // quit
    }

    // delete renamed file if it exists from a previous run
    if( neko.FileSystem.exists(dirname + "/renamed_" + fname) )
    {
      neko.FileSystem.deleteFile(dirname + "/renamed_" + fname);
      neko.Lib.println("deleted old renamed file");
    }

    // rename second new file
    neko.FileSystem.rename(dirname + "/duplicate_" + fname, dirname + "/renamed_" + fname);

    // check that rename was successfull
    if( !neko.FileSystem.exists(dirname + "/duplicate_" + fname) &&
    neko.FileSystem.exists(dirname + "/renamed_" + fname) )
      neko.Lib.println("rename successfull");
    else
    {
      neko.Lib.println("rename failed");
      neko.Sys.exit(1); // quit
    }

    // get directory listing for subdir
    var files = neko.FileSystem.readDirectory(dirname);
    neko.Lib.println("subdirectory listing:");
    for( ff in files)
      neko.Lib.println(" " + dirname + "/" + ff);

    // delete first copy
    neko.FileSystem.deleteFile(dirname + "/" + fname);

    // check that delete was successfull
    if( !neko.FileSystem.exists(dirname + "/" + fname) )
      neko.Lib.println("delete successfull");
    else
    {
      neko.Lib.println("delete failed");
      neko.Sys.exit(1); // quit
    }
  }
}

Compile and run with:

haxe -neko filesysex.n -main FileSystemExample
neko filesysex

The first time it runs, the output should resemble the output below. The file path and access times will differ. The direction of the path separators will be appropriate for the current operating system.

filename: c:\Haxe\filesystem\input.txt
file exists
Last access time: 2009-04-14 15:26:53
Last modification time: 2007-10-29 12:30:54
Last status change time: 2007-10-29 12:26:00
subdirectory subdir was created
copy successfull
rename successfull
subdirectory listing:
 subdir/input.txt
 subdir/renamed_input.txt
delete successfull

version #8341, modified 2010-03-21 14:58:58 by ianxm