Prova Pratica 2014.07.02

From Sistemi Operativi
(Redirected from Prova Pratica 02-07-2014)
Jump to navigation Jump to search

Soluzione di Maldus

Esercizio 1

prima parte:
Scrivere un programma che elenchi tutti i file di una directory.
mytx ddd ddd.tx
Ogni riga del file di output (secondo parametro) deve contenere la lunghezza, uno spazio e il nume del file. Dopo l'ultima riga
deve inserire una riga bianca.
ddd.t2 deve contenere l'elenco dei file regolari. Il primo campo e' un numero intero seguito da uno spazio, tutto cio' che segue
fino alla fine riga e' il nome del file.
es.
12 file1
235 file di prova
Seconda parte:
dopo la riga bianca inserire nel file di output (ordinatamente) il contenuto di tutti i file.
(quindi nel caso sopra i 12 byte di file1 seguiti dai 235 di “file di prova”).

Aggiornato per evitare che il file venga modificato tra la lettura della dimensione e del contenuto. Ho svolto l'esercizio considerando soltanto ddd.tx.

#include <dirent.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
 
#define SIZE 1024
 
int main(int argc, char* argv[]){
        struct dirent **entry_list;
        struct stat info;
        char *string, buf[SIZE], *temp;
        int n, i, f1 ,  readbytes;
	size_t size;
	FILE *stream, *f2 ;
        if( (n = scandir( argv[1], &entry_list, NULL, alphasort )) < 0 ){
                perror("scandir");
                exit(1);
        }
        chdir(argv[1]);
        if( (f1 = open( argv[2], O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) <0){
                perror("open");
                exit(1);
        }
	stream = open_memstream(&temp, &size);
        for( i=0; i < n; i++){
                stat(entry_list[i]->d_name, &info);
                if( !S_ISREG( info.st_mode) || !strcmp(argv[2], entry_list[i]->d_name) ) continue;
                asprintf(&string, "%i %s\n", info.st_size, entry_list[i]->d_name);
                write( f1, string, strlen(string));
                free(string);
		f2 = fopen( entry_list[i]->d_name, "r" );
		while( (readbytes = fread( buf, 1, SIZE, f2 ) )> 0 ){
                        fwrite( buf, 1 , readbytes, stream);
                }
		fclose(f2);
        }
        write( f1, "\n", 1 );
        rewind(stream) ;
	while( (readbytes = fread( buf, 1, SIZE, stream ) ) > 0 ){
		write( f1, buf, readbytes) ;
	}
        close(f1);
        fclose(stream);
        free(temp);
        return 0;
}

Esercizio 2

fare un programma che consenta di recuperare un file dal formato generato dall'esercizio1.
demytx file1 ddd.tx
deve creare il file 'file1' recuperando il contenuto dal file generato da myt2 dell'esercizio1
#include <dirent.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>

#define SIZE 1024

char* findname( char* line, char* name ){
        int i = 0;
        line[strlen(line)-1] = '\0';
        while(line[i]!='\0'){
                if( strcmp( line+i, name )==0) return line+i;
                i++;
        }
        return NULL ;
}


int main(int argc, char* argv[]){
        char buf[SIZE];
        char *line = NULL;
        char *name, *num ;
        int n = 1 , i, j, readbites, toskip = 0;
        FILE *f1, *f2 ;
        if( (f2 = fopen( argv[2], "r" ) ) == NULL ){
                perror("fopen");
                exit(1);
        }
        while( getline( &line, &n , f2 ) > 0){
                if( line[0] == '\n' ){
                        printf("file non presente\n");
                        exit(1);
                }
                if( (name = findname(line, argv[1])) != NULL ) break;
                toskip += atoi(line) ;
        }
        if( (f1= fopen(argv[1] ,"a")) == NULL ){
                perror("fopen");
                exit(1);
        }
        n = atoi(line);
        while( getline( &line, &i , f2 ) ) if( line[0] == '\n') break;
        while( toskip > 0 ) toskip -= fread(buf, 1, toskip, f2);
        while( n > 0 ){
                readbites = fread( buf, 1, n, f2 );
                fwrite( buf, 1, readbites, f1 );
                n -= readbites;
        }
        fclose(f1);
        fclose(f2);
        return 0;
}

Esercizio 3

Il comando che dovrete implementare come script shell o programma python e'  maxfreq.
Maxfreq ha come parametro un carattere alfanumerico e una directory.
Es:
maxfreq q  mydir 10
Cerca in tutto il sottoalbero del file system originato da mydir i 10 file che hanno la maggior frequenza della lettera indicata (in
questo caso la maggior frequenza di 'q'). Fornisce in output i nomi dei file e le frequenze in percentuale.
import os
import sys


result = []
char = sys.argv[1]
d = sys.argv[2]
num = int(sys.argv[3])
numr = 0
for dirName, subDirList, fileList in os.walk(d):
	for fname in fileList:
		n=0
		numr += 1
		fpath = os.path.join(dirName, fname)
		with open(fpath, "r") as f:
			for line in f:
				n += line.count(char)
			result.append( ( fpath, n, os.path.getsize(fpath)))

result=sorted( result, key=lambda x: x[1])
num = min(num, numr)
for i in range(num):
	if result[i][2] == 0: string = 'empty file'
	else: string= str( (result[i][1]*100)/result[i][2]) +'%' 
	print("%s %s" % (result[i][0], string ))