Last active
August 29, 2015 14:05
-
-
Save edomora97/04710b044a1205b03763 to your computer and use it in GitHub Desktop.
File reader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
class FileReader { | |
private: | |
FileReader(const FileReader&fr){} | |
int maxBufferSize,bufferSize,bufferPointer;int fileNo;char*buffer; | |
void loadBuffer(){bufferSize=read(fileNo,buffer,maxBufferSize);bufferPointer=0;} | |
inline char nextChar(){if(bufferPointer>=bufferSize)loadBuffer();return buffer[bufferPointer++];} | |
bool skipSpaces(){char c;while(((c=nextChar())==' '||c=='\n'||c=='\t')&&c!='\0');if(c=='\0')return 0;bufferPointer--;return 1;} | |
public: | |
FileReader(const char*_name,int _bufferSize=150000){buffer=(char*)malloc(_bufferSize);fileNo=open(_name,O_RDONLY);maxBufferSize=_bufferSize;loadBuffer();} | |
FileReader(int _fileNo,int _bufferSize=150000){buffer=(char*)malloc(_bufferSize);fileNo=_fileNo;maxBufferSize=_bufferSize;loadBuffer();} | |
~FileReader(){free(buffer);close(fileNo);} | |
int readInt(){return(int)readLongLong();} | |
long long readLongLong(){long long n=0;int mul=1;char c;if(!skipSpaces())abort();c=nextChar();if(c=='+'||c=='-')mul=(c=='+')?1:-1;else bufferPointer--;do{c=nextChar();if(c>='0'&&c<='9')n=n*10+(c-'0');}while(c>='0'&&c<='9');return n*mul;} | |
double readDouble(){double n=0;int mul=1,i=0,dotpos=0;char c;if(!skipSpaces())abort();c=nextChar();if(c=='+'||c=='-')mul=(c=='+')?1:-1;else bufferPointer--;do{i++;c=nextChar();if(c>='0'&&c<='9')n=n*10.0+(c-'0');if(c=='.')dotpos=i;}while((c>='0'&&c<= '9')||c=='.');if(dotpos>0)for(;dotpos<i-1;dotpos++)n/=10.0;return n*mul;} | |
int readString(char*str){if(!skipSpaces())return str[0]=0;char c;int l=0;do{c=nextChar();str[l++]=c;}while(c!=' '&&c!='\n'&&c!='\t'&&c!='\0');str[--l]='\0';return l;} | |
char readChar(){if(!skipSpaces())return'\0';return nextChar();} | |
}; | |
class FileWriter { | |
private: | |
FileWriter(const FileWriter&fr){} | |
char*buffer;int bufferPointer,bufferSize;int fileNo; | |
inline void flushBuffer(){if(write(fileNo,buffer,bufferPointer)==-1)abort();bufferPointer=0;} | |
inline void writeCharBuffer(char c){if(c!=0)buffer[bufferPointer++]=c;if(bufferPointer+5>=bufferSize)flushBuffer();} | |
public: | |
FileWriter(const char*path,int bufSize=100000){fileNo=open(path,O_CREAT|O_TRUNC|O_WRONLY,S_IRWXU|S_IRWXG|S_IRWXO);buffer=(char*)malloc(bufSize);bufferSize=bufSize;bufferPointer=0;} | |
FileWriter(int fd,int bufSize=100000){fileNo=fd;buffer=(char*)malloc(bufSize);bufferSize=bufSize;bufferPointer=0;} | |
~FileWriter(){flushBuffer();free(buffer);close(fileNo);} | |
void writeInt(int val,char sep='\n'){writeLongLong(val,sep);} | |
void writeLongLong(long long val,char sep='\n'){char buf[21];int point=0;bool neg=val<0;if(neg)val=-val;while(val>0){buf[point++]=(val%10)+'0';val/=10;}if(neg)writeCharBuffer('-');for(int i=point-1;i>=0;i--)writeCharBuffer(buf[i]);if(point==0)writeCharBuffer('0');writeCharBuffer(sep);} | |
void writeChar(char c,char sep='\n'){writeCharBuffer(c);writeCharBuffer(sep);} | |
void writeString(char* str,int l,char sep='\n'){while(l--){writeCharBuffer(str[0]);str++;}writeCharBuffer(sep);} | |
void flush(){flushBuffer();} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
/** | |
* Read a file (a lot) faster than scanf/cin | |
*/ | |
class FileReader { | |
private: | |
FileReader(const FileReader& fr) {} | |
int maxBufferSize, bufferSize, bufferPointer; | |
int fileNo; | |
char* buffer; | |
/** | |
* Load the buffer and replace the old one | |
*/ | |
void loadBuffer() { | |
bufferSize = read(fileNo, buffer, maxBufferSize); | |
// reset the pointer to the begin | |
bufferPointer = 0; | |
} | |
/** | |
* Get the next char from the buffer, if the buffer finish reload it | |
*/ | |
inline char nextChar() { | |
// reload the buffer if needed | |
if (bufferPointer >= bufferSize) | |
loadBuffer(); | |
return buffer[bufferPointer++]; | |
} | |
/** | |
* Skip all spaces (spaces, end line, tabulation). If the file finish | |
* return false | |
*/ | |
bool skipSpaces() { | |
char c; | |
while (((c = nextChar()) == ' ' || c == '\n' || c == '\t') && c != '\0') | |
; | |
if (c == '\0') | |
return 0; | |
// un-get the last chat | |
bufferPointer--; | |
return 1; | |
} | |
public: | |
/** | |
* Load the file and the buffer | |
* _name is the file name | |
* _bufferSize is the maximum amuount of memory used for the buffer | |
*/ | |
FileReader(const char* _name, int _bufferSize = 150000) { | |
buffer = (char*)malloc(_bufferSize); | |
fileNo = open(_name, O_RDONLY); | |
maxBufferSize = _bufferSize; | |
loadBuffer(); | |
} | |
/** | |
* Load from a file descriptor | |
* _fileNo is the file descriptor (must be opened in read mode! try STDIN_FILENO ;) | |
* _bufferSize is the maximum amount of memory used for the buffer | |
*/ | |
FileReader(int _fileNo, int _bufferSize = 150000) { | |
buffer = (char*)malloc(_bufferSize); | |
fileNo = _fileNo; | |
maxBufferSize = _bufferSize; | |
loadBuffer(); | |
} | |
/** | |
* Release the buffer | |
*/ | |
~FileReader() { | |
free(buffer); | |
close(fileNo); | |
} | |
/** | |
* Read the next integer from the buffer. Negative numbers are allowed | |
*/ | |
int readInt() { | |
int n = 0, mul = 1; | |
char c; | |
// if the file ends there isn't a number. So yeah | |
if (!skipSpaces()) abort(); | |
// try to parse the sign | |
c = nextChar(); | |
if (c == '+' || c == '-') | |
mul = (c == '+') ? 1 : -1; | |
else // if the sign is not present, un-get the read char | |
bufferPointer--; | |
do { | |
c = nextChar(); | |
if (c >= '0' && c <= '9') | |
n = n*10 + (c-'0'); | |
} while (c >= '0' && c <= '9'); | |
return n * mul; | |
} | |
/** | |
* Read a long long from the buffer. Negative #s are ok! | |
*/ | |
long long readLongLong() { | |
long long n = 0; | |
int mul = 1; | |
char c; | |
if (!skipSpaces()) abort(); | |
c = nextChar(); | |
if (c == '+' || c == '-') | |
mul = (c == '+') ? 1 : -1; | |
else | |
bufferPointer--; | |
do { | |
c = nextChar(); | |
if (c >= '0' && c <= '9') | |
n = n*10 + (c-'0'); | |
} while (c >= '0' && c <= '9'); | |
return n * mul; | |
} | |
/** | |
* Read a double from the buffer. Formats allowed are: | |
* 0.1 | |
* 1 | |
* -1 | |
* -1.0 | |
* .0 | |
* -.0 | |
*/ | |
double readDouble() { | |
double n = 0; | |
int mul = 1, i = 0; | |
int dotpos = 0; | |
char c; | |
if (!skipSpaces()) abort(); | |
c = nextChar(); | |
if (c == '+' || c == '-') | |
mul = (c == '+') ? 1 : -1; | |
else | |
bufferPointer--; | |
do { | |
i++; | |
c = nextChar(); | |
if (c >= '0' && c <= '9') | |
n = n*10.0 + (c-'0'); | |
if (c == '.') | |
dotpos = i; | |
} while ((c >= '0' && c <= '9') || c == '.'); | |
// if there is the dot | |
if (dotpos > 0) | |
for (; dotpos < i-1; dotpos++) | |
n /= 10.0; | |
return n * mul; | |
} | |
/** | |
* Read a string from the buffer. Spaces, tabs, endlines, EOF | |
* terminate the string | |
*/ | |
int readString(char* str) { | |
// no string, no party | |
if (!skipSpaces()) | |
return str[0] = 0; | |
char c; | |
int l = 0; | |
do { | |
c = nextChar(); | |
str[l++] = c; | |
} while (c != ' ' && c != '\n' && c != '\t' && c != '\0'); | |
str[--l] = '\0'; | |
return l; | |
} | |
/** | |
* Read a single char (skipping spaces before) | |
*/ | |
char readChar() { | |
if (!skipSpaces()) | |
return '\0'; | |
return nextChar(); | |
} | |
}; | |
#include <assert.h> | |
#include <time.h> | |
int main() { | |
printf("BENCHMARK FileReader\n"); | |
const int N_SAMPLES = 10000000; | |
int* v; | |
bool custom = false; | |
// try to open the file | |
FILE* in = fopen("sample.txt", "r"); | |
// if not present, generate it! | |
if (in == NULL) { | |
printf("Generazione file...\n"); | |
// generate a random vector | |
v = (int*)malloc(N_SAMPLES * sizeof(int)); | |
for (int i = 0; i < N_SAMPLES; i++) | |
v[i] = rand(); | |
printf("Scrittura file...\n"); | |
// write the vector to file | |
FILE* out = fopen("sample.txt", "w"); | |
fprintf(out, "%d\n", N_SAMPLES); | |
for (int i = 0; i < N_SAMPLES; i++) | |
fprintf(out, "%d\n", v[i]); | |
fclose(out); | |
// open the new file | |
in = fopen("sample.txt", "r"); | |
} else { | |
printf("File già presente...\n"); | |
// confronto con il vettore generato = mi sa proprio di no :( | |
custom = true; | |
} | |
/* | |
* Formato file sample.txt | |
* Prima riga N, numero elementi | |
* Successive N righe, elementi | |
*/ | |
printf("fscanf : "); | |
time_t start1 = clock() / (CLOCKS_PER_SEC / 1000); | |
int N1; assert(1 == fscanf(in, "%d", &N1)); | |
// se è custom alloca un nuovo vettore | |
// altrimenti controlla la dimensione letta | |
if (custom) v = (int*)malloc(N1 * sizeof(int)); | |
if (!custom) assert(N1 == N_SAMPLES); | |
int x; | |
for (int i = 0; i < N1; i++) { | |
assert( 1 == fscanf(in, "%d", &x) ); | |
// se non è custom allora controlla con il vettore generato, | |
// altrimenti salva x | |
if (!custom) assert(x == v[i]); | |
else v[i] = x; | |
} | |
time_t end1 = clock() / (CLOCKS_PER_SEC / 1000); | |
printf("%ld ms\n", end1-start1); | |
printf("FileReader: "); | |
time_t start2 = clock() / (CLOCKS_PER_SEC / 1000); | |
FileReader fr("sample.txt"); | |
int N2 = fr.readInt(); | |
// controlla la dimensione letta | |
if (!custom) assert(N2 == N_SAMPLES); | |
assert(N1 == N2); | |
for (int i = 0; i < N2; i++) { | |
x = fr.readInt(); | |
// il numero letto deve corrispondere a quello nel vettore | |
assert(x == v[i]); | |
} | |
time_t end2 = clock() / (CLOCKS_PER_SEC / 1000); | |
printf("%ld ms\n", end2-start2); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
/** | |
* Write a file (a lot) faster than printf/cout | |
*/ | |
class FileWriter { | |
private: | |
FileWriter(const FileWriter& fr) {} | |
char* buffer; | |
int bufferPointer, bufferSize; | |
int fileNo; | |
/** | |
* Write the buffer to file | |
*/ | |
inline void flushBuffer() { | |
if (write(fileNo, buffer, bufferPointer) == -1) | |
abort(); | |
bufferPointer = 0; | |
} | |
/** | |
* Write a char into the buffer. Flush it if needed | |
*/ | |
inline void writeCharBuffer(char c) { | |
if (c != 0) | |
buffer[bufferPointer++] = c; | |
if (bufferPointer+5 >= bufferSize) | |
flushBuffer(); | |
} | |
public: | |
/** | |
* Open the file for writing. If the file doesn't exists, it will be | |
* created | |
* path: the file path | |
* bufSize: the size of the buffer | |
*/ | |
FileWriter(const char* path, int bufSize = 100000) { | |
fileNo = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO); | |
buffer = (char*)malloc(bufSize); | |
bufferSize = bufSize; | |
bufferPointer = 0; | |
} | |
/** | |
* Use an already open file descriptor. Warning! if the same file | |
* is used with an other library it could become incoerent | |
* fd: the file descriptor open in writing | |
* bufSize: the size of the buffer | |
*/ | |
FileWriter(int fd, int bufSize = 100000) { | |
fileNo = fd; | |
buffer = (char*)malloc(bufSize); | |
bufferSize = bufSize; | |
bufferPointer = 0; | |
} | |
/** | |
* Release the buffer and close the file | |
*/ | |
~FileWriter() { | |
flushBuffer(); | |
free(buffer); | |
close(fileNo); | |
} | |
/** | |
* Write an integer into the buffer. sep will be appended after | |
*/ | |
void writeInt(int val, char sep = '\n') { | |
writeLongLong(val, sep); | |
} | |
/** | |
* Write a long integer into the buffer. sep will be appended after | |
*/ | |
void writeLongLong(long long val, char sep = '\n') { | |
char buf[21]; int point = 0; | |
bool neg = val < 0; | |
if (neg) val = -val; | |
while (val > 0) { | |
buf[point++] = (val % 10) + '0'; | |
val /= 10; | |
} | |
if (neg) writeCharBuffer('-'); | |
for (int i = point-1; i >= 0; i--) | |
writeCharBuffer(buf[i]); | |
if (point == 0) writeCharBuffer('0'); | |
writeCharBuffer(sep); | |
} | |
/** | |
* Write a char into the buffer. sep will be appended after | |
*/ | |
void writeChar(char c, char sep = '\n') { | |
writeCharBuffer(c); | |
writeCharBuffer(sep); | |
} | |
/** | |
* Write a string of l charaters into the buffer. sep will be | |
* appended after | |
*/ | |
void writeString(char* str, int l, char sep = '\n') { | |
while (l--) { | |
writeCharBuffer(str[0]); | |
str++; | |
} | |
writeCharBuffer(sep); | |
} | |
/** | |
* Flush the buffer | |
*/ | |
void flush() { | |
flushBuffer(); | |
} | |
}; | |
char str[1000]; | |
int main() { | |
FileWriter fw("out.txt", 100000); | |
fw.writeInt(123); | |
fw.writeInt(1234567890); | |
fw.writeInt(-1234567890); | |
fw.writeLongLong(0); | |
fw.writeLongLong(1234567890123456789); | |
fw.writeLongLong(-1234567890123456789); | |
fw.writeChar('a', ' '); | |
fw.writeChar('b', '\0'); | |
fw.writeChar('c'); | |
for (int i = 0; i < 1000-1; i++) str[i] = 'a'; | |
str[1000-1] = 0; | |
fw.writeString(str, 1000); | |
fw.flush(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment