This assignment is to get you to handle buffered IO where you do the buffering. You will see in this assignment that you
Posted: Tue Jul 12, 2022 8:22 am
This assignment is to get you to handle buffered IO where you dothe buffering.
You will see in this assignment that you may question why youare doing operations the way specified here in the assignment. Thisis because we are writing a buffering I/O. We will see later infile system project how important this is.
You are to create a set of routines in a file called `b_io.c`,skeleton of this file is provided. The prototypes for thesefunctions are in a file called `b_io.h` (provided). The Makefile issupplied and you should set your FIRSTNAME and LASTNAME. (make noother changes to the Makefile)
You will be just writing three functions in `b_io.c`
```
b_io_fd b_open (char * filename, int flags);
int b_read (b_io_fd fd, char * buffer, int count);
int b_close (b_io_fd fd);
```
Your functions here will only use the supplied lowlevel APIs.i.e. LBAread, and GetFileInfo.
The `b_open` should return a integer file descriptor (a numberthat you can track the file). You may want to also allocate the 512(B_CHUNK_SIZE) byte buffer you will need for read operations here.Make sure though you know how to track the buffer for eachindividual file. Return a negative number if there is an error. Youwill call GetFileInfo to find the filesize and location of thedesired file. See the structure fileInfo. GetFileInfo returns apointer to fileInfo (this pointer does NOT need to be freed). Thatstructure has the starting block number (all files are contiguouslyallocated) for the file and the files actual byte length.
The `b_read` takes a file descriptor, a buffer and the number ofbytes desired. The Operation of your `b_read` function must onlyread B_CHUNK_SIZE byte chunks at a time from LBAread into your ownbuffer, you will then copy the appropriate bytes from your bufferto the caller’s buffer. This means you may not even need to do aread of the actual file if your buffer already has the data needed.Or, it may mean that you have some bytes in the buffer, but notenough and have to transfer what you have, read the nextB_CHUNK_SIZE bytes, then copy the remaining needed bytes to thecaller’s buffer.
The return value is the number of bytes you have transferred tothe caller’s buffer. When it is positive but less than the request,it means you have reached the end of file.
Hint: You may also need to track between calls where in thebuffer you left off, and which block of the file you are at.
You also need to be able to handle if the read request isgreater than B_CHUNK_SIZE, meaning that you may have to directlyfill the caller's buffer from a B_CHUNK_SIZE byte read (no need tobuffer) then buffer just any amount needed to complete the caller'sread request.
You are also responsible for keeping track of the file size, andonce you reach the end of file, return 0 indicating there are nomore bytes to read.
The `b_close` should free any resources you were using.
You can write additional helper routines as needed.
Limits: You can assume no more than 20 files open at a time.(i.e. you need to ensure that multiple files can be open at onetime, so the buffer you have for a file can not be global, but mustbe associated with that open file. A function to get an availableFile Control Block (FCB) is provided in b_io.c.
The main program (buffer-main.o, provided) uses the command linearguments to specify data file and the desired target file(s).
The main program uses `b_open`, reads some variable number ofcharacters at a time from the file using `b_read`, prints thosecharacters to the screen (ending in a newline character), and loopsuntil it has read the entire file, then `b_close` the file andexit. The program may open multiple files at one time and willrequest on chunk and print that one for each file, so the outputwill contain a line from file 1 than a line from file 2, etc untilthe end of file.
You are provided the file DATA as the file you are accessing andthat contains the files IHaveADream.txt, CommonSense.txt,DecOfInd.txt. Think of that file as the "hard drive".
The output will vary each run but at the end you should see:
```
We have read 8120 characters from file DecOfInd.txt
We have read 1877 characters from file CommonSense.txt
```
You should submit your source code file(s) and Makefile, alongwith a writeup in PDF format using the writeup template thatincludes a description of what you did, show me the logic and stepsyou define to complete this project and the compilation andexecution output from your program in GitHub, and the PDF also inCanvas. There is no Analysis section needed for thisassignment.
The ONLY files you will modify is the `Makefile` and `b_io.c`(you will not be creating any new files)
Rubric
| Grade Item | Grade Points |
|:---------------------------------------------|----------------------------------------------:|
| Standard Header | 2 |
| Proper open and malloc | 15 |
| Proper tracking and implementation of read | 20 |
| Proper buffering | 25 |
| Proper implementation of close and free | 5 |
| Correct Output | 10 |
| Code Comments | 10 |
| Writeup | 13 (Description, Compilation, Sample Output) |
.h header file .
#ifndef _B_IO_H
#define _B_IO_H
typedef int b_io_fd;
b_io_fd b_open (char * filename, int flags);
int b_read (b_io_fd fd, char * buffer, int count);
int b_close (b_io_fd fd);
#endif
.C file
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "b_io.h"
#include "fsLowSmall.h"
#define MAXFCBS 20 //The maximum number of files open at onetime
// This structure is all the information needed to maintain anopen file
// It contains a pointer to a fileInfo strucutre and any otherinformation
// that you need to maintain your open file.
typedef struct b_fcb
{
fileInfo * fi; //holds the low level systems file info
// Add any other needed variables here to track the individualopen file
} b_fcb;
//static array of file control blocks
b_fcb fcbArray[MAXFCBS];
// Indicates that the file control block array has not beeninitialized
int startup = 0;
// Method to initialize our file system / file controlblocks
// Anything else that needs one time initialization can go inthis routine
void b_init ()
{
if (startup)
return; //already initialized
//init fcbArray to all free
for (int i = 0; i < MAXFCBS; i++)
{
fcbArray.fi = NULL; //indicates a free fcbArray
}
startup = 1;
}
//Method to get a free File Control Block FCB element
b_io_fd b_getFCB ()
{
for (int i = 0; i < MAXFCBS; i++)
{
if (fcbArray.fi == NULL)
{
fcbArray.fi = (fileInfo *)-2; // used but not assigned
return i; //Not thread safe but okay for this project
}
}
return (-1); //all in use
}
// b_open is called by the "user application" to open a file.This routine is
// similar to the Linux open function.
// You will create your own file descriptor which is just aninteger index into an
// array of file control blocks (fcbArray) that you maintain foreach open file.
b_io_fd b_open (char * filename, int flags)
{
if (startup == 0) b_init(); //Initialize our system
//*** TODO ***: Write open function to return your filedescriptor
// You may want to allocate the buffer here as well
// But make sure every file has its own buffer
// This is where you are going to want to call GetFileInfo andb_getFCB
}
// b_read functions just like its Linux counterpart read. Theuser passes in
// the file descriptor (index into fcbArray), a buffer wherethay want you to
// place the data, and a count of how many bytes they want fromthe file.
// The return value is the number of bytes you have copied intotheir buffer.
// The return value can never be greater then the requestedcount, but it can
// be less only when you have run out of bytes to read. i.e. Endof File
int b_read (b_io_fd fd, char * buffer, int count)
{
//*** TODO ***:
// Write buffered read function to return the data and # bytesread
// You must use LBAread and you must buffer the data inB_CHUNK_SIZE byte chunks.
if (startup == 0) b_init(); //Initialize our system
// check that fd is between 0 and (MAXFCBS-1)
if ((fd < 0) || (fd >= MAXFCBS))
{
return (-1); //invalid file descriptor
}
// and check that the specified FCB is actually in use
if (fcbArray[fd].fi == NULL) //File not open for thisdescriptor
{
return -1;
}
// Your Read code here - the only function you call to get datais LBAread.
// Track which byte in the buffer you are at, and which block inthe file
}
// b_close frees and allocated memory and places the filecontrol block back
// into the unused pool of file control blocks.
int b_close (b_io_fd fd)
{
//*** TODO ***: Release any resources
}
You will see in this assignment that you may question why youare doing operations the way specified here in the assignment. Thisis because we are writing a buffering I/O. We will see later infile system project how important this is.
You are to create a set of routines in a file called `b_io.c`,skeleton of this file is provided. The prototypes for thesefunctions are in a file called `b_io.h` (provided). The Makefile issupplied and you should set your FIRSTNAME and LASTNAME. (make noother changes to the Makefile)
You will be just writing three functions in `b_io.c`
```
b_io_fd b_open (char * filename, int flags);
int b_read (b_io_fd fd, char * buffer, int count);
int b_close (b_io_fd fd);
```
Your functions here will only use the supplied lowlevel APIs.i.e. LBAread, and GetFileInfo.
The `b_open` should return a integer file descriptor (a numberthat you can track the file). You may want to also allocate the 512(B_CHUNK_SIZE) byte buffer you will need for read operations here.Make sure though you know how to track the buffer for eachindividual file. Return a negative number if there is an error. Youwill call GetFileInfo to find the filesize and location of thedesired file. See the structure fileInfo. GetFileInfo returns apointer to fileInfo (this pointer does NOT need to be freed). Thatstructure has the starting block number (all files are contiguouslyallocated) for the file and the files actual byte length.
The `b_read` takes a file descriptor, a buffer and the number ofbytes desired. The Operation of your `b_read` function must onlyread B_CHUNK_SIZE byte chunks at a time from LBAread into your ownbuffer, you will then copy the appropriate bytes from your bufferto the caller’s buffer. This means you may not even need to do aread of the actual file if your buffer already has the data needed.Or, it may mean that you have some bytes in the buffer, but notenough and have to transfer what you have, read the nextB_CHUNK_SIZE bytes, then copy the remaining needed bytes to thecaller’s buffer.
The return value is the number of bytes you have transferred tothe caller’s buffer. When it is positive but less than the request,it means you have reached the end of file.
Hint: You may also need to track between calls where in thebuffer you left off, and which block of the file you are at.
You also need to be able to handle if the read request isgreater than B_CHUNK_SIZE, meaning that you may have to directlyfill the caller's buffer from a B_CHUNK_SIZE byte read (no need tobuffer) then buffer just any amount needed to complete the caller'sread request.
You are also responsible for keeping track of the file size, andonce you reach the end of file, return 0 indicating there are nomore bytes to read.
The `b_close` should free any resources you were using.
You can write additional helper routines as needed.
Limits: You can assume no more than 20 files open at a time.(i.e. you need to ensure that multiple files can be open at onetime, so the buffer you have for a file can not be global, but mustbe associated with that open file. A function to get an availableFile Control Block (FCB) is provided in b_io.c.
The main program (buffer-main.o, provided) uses the command linearguments to specify data file and the desired target file(s).
The main program uses `b_open`, reads some variable number ofcharacters at a time from the file using `b_read`, prints thosecharacters to the screen (ending in a newline character), and loopsuntil it has read the entire file, then `b_close` the file andexit. The program may open multiple files at one time and willrequest on chunk and print that one for each file, so the outputwill contain a line from file 1 than a line from file 2, etc untilthe end of file.
You are provided the file DATA as the file you are accessing andthat contains the files IHaveADream.txt, CommonSense.txt,DecOfInd.txt. Think of that file as the "hard drive".
The output will vary each run but at the end you should see:
```
We have read 8120 characters from file DecOfInd.txt
We have read 1877 characters from file CommonSense.txt
```
You should submit your source code file(s) and Makefile, alongwith a writeup in PDF format using the writeup template thatincludes a description of what you did, show me the logic and stepsyou define to complete this project and the compilation andexecution output from your program in GitHub, and the PDF also inCanvas. There is no Analysis section needed for thisassignment.
The ONLY files you will modify is the `Makefile` and `b_io.c`(you will not be creating any new files)
Rubric
| Grade Item | Grade Points |
|:---------------------------------------------|----------------------------------------------:|
| Standard Header | 2 |
| Proper open and malloc | 15 |
| Proper tracking and implementation of read | 20 |
| Proper buffering | 25 |
| Proper implementation of close and free | 5 |
| Correct Output | 10 |
| Code Comments | 10 |
| Writeup | 13 (Description, Compilation, Sample Output) |
.h header file .
#ifndef _B_IO_H
#define _B_IO_H
typedef int b_io_fd;
b_io_fd b_open (char * filename, int flags);
int b_read (b_io_fd fd, char * buffer, int count);
int b_close (b_io_fd fd);
#endif
.C file
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "b_io.h"
#include "fsLowSmall.h"
#define MAXFCBS 20 //The maximum number of files open at onetime
// This structure is all the information needed to maintain anopen file
// It contains a pointer to a fileInfo strucutre and any otherinformation
// that you need to maintain your open file.
typedef struct b_fcb
{
fileInfo * fi; //holds the low level systems file info
// Add any other needed variables here to track the individualopen file
} b_fcb;
//static array of file control blocks
b_fcb fcbArray[MAXFCBS];
// Indicates that the file control block array has not beeninitialized
int startup = 0;
// Method to initialize our file system / file controlblocks
// Anything else that needs one time initialization can go inthis routine
void b_init ()
{
if (startup)
return; //already initialized
//init fcbArray to all free
for (int i = 0; i < MAXFCBS; i++)
{
fcbArray.fi = NULL; //indicates a free fcbArray
}
startup = 1;
}
//Method to get a free File Control Block FCB element
b_io_fd b_getFCB ()
{
for (int i = 0; i < MAXFCBS; i++)
{
if (fcbArray.fi == NULL)
{
fcbArray.fi = (fileInfo *)-2; // used but not assigned
return i; //Not thread safe but okay for this project
}
}
return (-1); //all in use
}
// b_open is called by the "user application" to open a file.This routine is
// similar to the Linux open function.
// You will create your own file descriptor which is just aninteger index into an
// array of file control blocks (fcbArray) that you maintain foreach open file.
b_io_fd b_open (char * filename, int flags)
{
if (startup == 0) b_init(); //Initialize our system
//*** TODO ***: Write open function to return your filedescriptor
// You may want to allocate the buffer here as well
// But make sure every file has its own buffer
// This is where you are going to want to call GetFileInfo andb_getFCB
}
// b_read functions just like its Linux counterpart read. Theuser passes in
// the file descriptor (index into fcbArray), a buffer wherethay want you to
// place the data, and a count of how many bytes they want fromthe file.
// The return value is the number of bytes you have copied intotheir buffer.
// The return value can never be greater then the requestedcount, but it can
// be less only when you have run out of bytes to read. i.e. Endof File
int b_read (b_io_fd fd, char * buffer, int count)
{
//*** TODO ***:
// Write buffered read function to return the data and # bytesread
// You must use LBAread and you must buffer the data inB_CHUNK_SIZE byte chunks.
if (startup == 0) b_init(); //Initialize our system
// check that fd is between 0 and (MAXFCBS-1)
if ((fd < 0) || (fd >= MAXFCBS))
{
return (-1); //invalid file descriptor
}
// and check that the specified FCB is actually in use
if (fcbArray[fd].fi == NULL) //File not open for thisdescriptor
{
return -1;
}
// Your Read code here - the only function you call to get datais LBAread.
// Track which byte in the buffer you are at, and which block inthe file
}
// b_close frees and allocated memory and places the filecontrol block back
// into the unused pool of file control blocks.
int b_close (b_io_fd fd)
{
//*** TODO ***: Release any resources
}