|
|
c m s c 311
f a l l 2 0 0 2 |
If you read in an unsigned int equal to 0xdabedabe, then this must mean the file is the same as yours. If it's some other value, then it must be a different endian-ness.
| static vector<unsigned int> loadValues( const string & fileName ) ; |
|
If the file exists (in the current directory), read in the first
unsigned int, and determine the endian-ness. If this is the
same as your machine's endian-ness, read the rest of the values
normally. Thus, if there are N * 4 bytes in the file, you will
read in (N - 1) unsigned int values (after the initial 4 byte
header with 0xdabedabe), and store them in a vector of unsigned ints.
If the endian-ness is not the same as your machine, then you still read in the N - 1 values, but then afterwards, you must convert the values so they are the same endian-ness as your machine. (Thus, for each unsigned int, you must swap bytes 0 and 3 and bytes 1 and 2, assuming byte 0 is the least significant byte, and byte 3 is the most significant byte). If the file does not exist, then just return an empty vector. You can assume that there is at least 8 bytes in the file if it does exist (i.e., it has the 4 byte header plus at least one 4 byte integer). |
| static bool writeValues( const string & fileName, vector<unsigned int> values, bool isBigEndian ) ; |
|
In this version, you will write out the values given the endian-ness.
Add the header as needed (0xdabedabe). This may involve swapping bytes.
If you read in the file, then call this function with the same endian-ness
as the file, then print out the file, you should get the equivalent file
(you can run "diff" to see if they result in the same binary).
If the file exists, then return false, and don't do anything. |
int fd ; // fd is called a file descriptor
ssize_t w1, w2 ;
char header1[ 512 ], header2[ 1024 ] ;
// Opens a file to be written, but only if file does not already exist.
if ( ( fd = open( "newfile", O_WRONLY|O_CREAT|O_EXCL, 0644 ) ) == -1 )
{
cout << "Error opening file" << endl ;
return -1 ;
}
w1 = write( fd, header1, 512 ) ;
w2 = write( fd, header1, 1024 ) ;
// close the file
close( fd ) ;
The write function takes a file descriptor of an opened
file, a pointer to some array (any type) or even just a plain
structure or variable, and the number of bytes that will be
written. The function returns an int-like value telling you
how many bytes were actually written.
To open a file for reading (in C),
int fd ; // fd is called a file descriptor
ssize_t n1, n2 ;
char buf[ 512 ], buf2[ 1024 ] ;
// Opens a file for read only
if ( ( fd = open( "oldfile", O_RDONLY ) ) == -1 )
{
cout << "Error opening file" << endl ;
return -1 ;
}
n1 = read( fd, buf1, 512 ) ;
n2 = read( fd, buf2, 1024 ) ;
// close the file
close( fd ) ;
Nelson Padua-Perez offers the C++ solution.
Note: you should switch "Person" to unsigned int.
#include <iostream.h>
#include <stdlib.h>
#include <fstream.h>
struct Person
{
int id;
float salary;
};
// write takes a char *, and the number of bytes
void create_file(char *filename)
{
int x;
Person p;
ofstream out(filename, ios::out);
if (!out)
{
cerr << "File opening failed!" << endl;
exit(1);
}
for (x = 1; x <= 5; x++)
{
p.id = x;
p.salary = x * 100;
out.write(reinterpret_cast<const char *>(&p), sizeof(Person));
}
}
// read takes a char * pointer, and the number of bytes.
// Notice you can store into any object---endian-ness is an
// issue, however. If the file stores in big-endian, and the machine
// is little-endian, the number will be read in the wrong order.
// There's no information in the file to determine endian-ness.
void read_file(char *filename)
{
int x;
Person p;
ifstream in(filename, ios::in);
if (!in)
{
cerr << "File opening failed!" << endl;
exit(1);
}
for (x = 1; x <= 5; x++)
{
in.read(reinterpret_cast<char *>(&p), sizeof(Person));
cout << "ID: " << p.id << " , SALARY " << p.salary << endl;
}
}
void read_entry(int id, char *filename)
{
Person p;
ifstream in(filename, ios::in);
in.seekg((id - 1) * sizeof(Person));
in.read(reinterpret_cast<char *>(&p), sizeof(Person));
cout << "SID: " << p.id << " , SSALARY " << p.salary << endl;
}
void write_entry(int id, float salary, char *filename)
{
Person p;
ofstream out(filename, ios::out);
p.id = id;
p.salary = salary;
out.seekp((id - 1) * sizeof(Person));
out.write(reinterpret_cast<const char *>(&p), sizeof(Person));
}
int main()
{
create_file("data");
read_file("data"); // sequential reading
cout << "READING ENTRY" << endl;
read_entry(2, "data");
cout << "RANDOM WRITING" << endl;
write_entry(2, 1345, "data");
read_entry(2, "data");
return 0;
}
OUTPUT
% a.out
ID: 1 , SALARY 100
ID: 2 , SALARY 200
ID: 3 , SALARY 300
ID: 4 , SALARY 400
ID: 5 , SALARY 500
READING ENTRY
SID: 2 , SSALARY 200
RANDOM WRITING
SID: 2 , SSALARY 1345
%
|
See the class syllabus for policies concerning email Last Modified: Fri Sep 27 19:41:52 EDT 2002 |
|
|
|
|
|