Exercises:Files: Difference between revisions

From COMP15212 Wiki
pc>Yuron
No edit summary
gravatar W81054ch [userbureaucratinterface-adminsysopPHRhYmxlIGNsYXNzPSJ0d3BvcHVwIj48dHI+PHRkIGNsYXNzPSJ0d3BvcHVwLWVudHJ5dGl0bGUiPkdyb3Vwczo8L3RkPjx0ZD51c2VyPGJyIC8+YnVyZWF1Y3JhdDxiciAvPmludGVyZmFjZS1hZG1pbjxiciAvPnN5c29wPGJyIC8+PC90ZD48L3RyPjwvdGFibGU+] (talk | contribs)
m (1 revision imported)
 
(No difference)

Latest revision as of 10:22, 9 August 2019

On path: Exercises 0: Exercises • 1: Pointer Exercise • 2: Arguments Exercise • 3: Malloc Exercise • 4: Structs Exercise • 5: Processes Exercise • 6: Shared memory Exercise • 7: Pipes Exercise • 8: Exceptions Exercise • 9: Synchronisation Exercise • 10: Files Exercise • 11: Threads Exercise • 12: Unix proc Exercise
Depends on Pointers

Download exercise files

This exercise is concerned with file access and file attributes. The purposes of this exercise are:

  • to demonstrate some basic principles of file handling
  • to reveal some details of a file’s attributes

This exercise uses C calls for access to the file system, not the underlying O.S. calls. However, although details vary the principles are similar.

Part 1

Compile and run the example file_output.c on a Unix machine. Be patient!

The code copies input from an internal string to an output ‘file’; initially this is the stream stdout but the behaviour is very similar.

You can check this later by swapping the fputc() (file put character) call for the printf().

To make a visible point here, there is a 1 s pause between each character output. The issue is that the characters are output to a buffer and the buffer is copied to the display at some later time. In the case of the display (stdout) the buffer is flushed at each newline (’\n’), hence the long wait and then a whole line ‘pops up’.

Uncomment the line with the fflush() call and repeat the exercise. This is slightly more interesting to watch as buffer-flushing is forced each time around the loop. This is generally less efficient as many more O.S. calls can be needed.

Experiment with writing to a file instead of (or as well as) stdout. There is already a call in place (commented) which writes to a file handle and the fopen() and fclose() are also in place.

It should be possible to demonstrate that the file output buffer is not flushed on a ‘\n’, only when it has assembled enough data to make a write operation to the disk worthwhile – or the file is closed — or you flush it yourself.

Exercise: work out how to input from a file and prove (to yourself) that you have read the information. Try to do this – at least on paper – before proceeding to Part 2.

Part 2

Compile and run the example file_input.c on a Unix machine. We recommend you also download the test file Hamlet.txt.

Run the application with a filename (string) and two numeric arguments, like this:

./file_input Hamlet.txt 88840 382

When that has worked okay, explore and understand the source code. It:

  • establishes that it has the arguments it needs
    • using a library to convert some strings to integers
  • opens the chosen file
    • testing that this was successful
  • seeks the chosen position
  • loops, outputting characters in a rather crude way
    • but remembering to check if you’ve fallen out of the file extent
  • reports the new file position indicator (ftell())
  • closes the file

Part 3

Compile and run the example file_stat.c on a Unix machine. This illustrates the extraction of file attributes and will print out some of the attributes for a file name which you supply. For example (as supplied) it prints UID which is the unique User IDentifier (on that system) for the file’s owner.

You can find your own UID – or anyone else’s – with the shell command id -u <username>.

Try this with (e.g.) a system file too – probably owned by root (UID 0).

The example also includes a simple use of errno, the error code returned by the system call. Include a non-existent filename in your experiments too.

Now play!

Puzzle/challenge

Show something of what you now understand with file manipulation with a little example. Here’s one suggestion, using techniques included above:

Create a program to which you give a directory name and it plants creates a short text file within that directory. BUT it should detect and inform the user (as politely as you wish!) if:

  • the specified directory does not exist
  • the specified ‘directory’ exists, but is not a directory

Revision

Three types of pointer operation have been included in this example:

  • *p_char” gets the item (char, in this case) at the address held by p_char.
  • p_char++;” increments the pointer by one element, moving it along the string.
  • &(buffer.st_mtime)” finds the address of a particular field in the struct called “buffer”.

There is also some use of command line arguments.