I FILE di dati in C#
flusso di dati di un file FileStream flusso di dati di un file tra Memoria di Massa e la RAM Viene aperto un canale di comunicazione tra MM e RAM. Viene definito un nome fittizio che avrà il collegamento (lo streaming) e viene indicato il file con relativo percorso. RAM Random Access Memory Memoria di massa (qui hard disk) Lo streaming si apre, si attiva così: FileStream nomefs = new FileStream(@“nomefile.dat", FileMode.modalità);
FileMode determina la tipologia di contatto (la direzione) e come verrà gestito il file FileMode.Open FileMode.CreateNew RAM Random Access Memory Memoria di massa (qui hard disk) FileMode.Append
Il collegamento è pronto ma … è necessario destinare un buffer di memoria al trasferimento dei dati. Si tratta del BinaryReader o del BinaryWriter. Ognuno di essi può compiere solo una delle due azioni: read oppure write. Inoltre, può esistere solo se lo streaming è aperto in modo coerente. Il punto nel file in cui agiranno (in lettura o in scrittura) i nostri oggetti Binary sarà determinato dal FileMode (all’inizio, alla fine ..).
La sintassi è BinaryReader nomeBR = new BinaryReader( nome del FileStream); oppure BinaryWriter nomeBR = new BinaryWriter ( nome del FileStream); Se dobbiamo svolgere operazioni diverse e quindi occorrono più oggetti Binary, ricordiamoci di dare nomi coerenti. Capiamo meglio…..
BR FileMode.Open FSLettura BW1 FileMode. CreateNew FSScrittura RAM Random Access Memory BW2 Memoria di massa (qui hard disk) FileMode. Append FSAggiunta (nel flusso il nome del FileStream e sull’omino il nome dell’oggetto Binary)
BR.ReadString (); Cosa può fare??? LEGGERE cioè trasferire un dato dalla MM alla RAM BR.ReadString (); BR FileMode.Open R A M M M FSLettura Come lo utilizzo? Eseguendo un assegnamento Num= BR.ReadDecimal(); TxtCarattere= BR.ReadChar(); Amico.Nome= BR.ReadString(); (anche in Grid) Testando direttamente il dato If (BR.ReadBoolean()) …. If (BR.ReadString=“Milano”) …. Eseguendo un output Console.WriteLine(BR.ReadString()); Console.WriteLine(BR.ReadDecimal()); Console.WriteLine(BR.ReadBoolean()); Console.WriteLine(BR.ReadByte()); Console.WriteLine(BR.ReadInt32()); Console.WriteLine(BR.ReadChar());
BR.ReadString (); Cosa può fare??? SCRIVERE cioè trasferire un dato dalla RAM alla MM BR.ReadString (); BW1 FileMode. CreateNew o Append R A M M M FSScrittura o FSAggiunta Come lo utilizzo? Tipicamente da Text (anche da Grid) BW1.Write(TxtCogno.Text); BW1.Write(Amico.Nome); BW1.Write(Num); … … Non dimenticare: BWNome.Close(); FsNome.Close();
Alcune precisazioni…. Il FilStream può essere dichiarato in vari punti del programma: in un singolo metodo (se serve solo lì) oppure a livello di public partial class . Non può essere allocato 2 volte. Nemmeno si possono creare 2 FileStream in contemporanea sullo stesso file: questo significa che non possiamo dichiarne 2 al livello di public partial class, ma possiamo invece crearle in procedure diverse. La dichiarazione di un BinaryReader/Writer può avvenire solo dopo che la connessioni di streaming è avvenuta. Tale dichiarazione segue le normali regole di visibilità (esiste o non esiste a seconda di dove viene dichiarata). Conflitti (e quindi errori) possono sorgere se le regole di visibilità non vengono rispettate. Ricordarsi che: se il file è già esistente NON può essere ricreato se non esiste non può essere aperto né in modalità Open, ne in modalità Append.
Prima di procedere chiariamo che ogni operazione su FILE implica uno spostamento di un PUNTATORE all’interno del file stesso. FileMode.Open ………. puntatore all’inizio del file Br.Readstring() comporta un avanzamento e poi il trasferimento dati in RAM FileMode.Open Br.Readstring() Br.Readstring() ….. … Br.Readstring() datoA datoB datoF datoK datoL datoS datoA datoB datoF datoK datoL datoS datoA datoB datoF datoK datoL datoS datoA datoB datoF datoK datoL datoS RAM RAM RAM RAM datoB datoS datoA br.PeekChar() = -1
Prima di procedere chiariamo che ogni operazione su FILE implica uno spostamento di un PUNTATORE all’interno del file stesso. FileMode.Append -> puntatore dopo l’ultimo record Bw.Write(…) comporta prima un avanzamento e poi la registrazione del dato su file. FileMode.Append Bw.Write() FileMode.Createnew FileMode.Create Bw.Write() datoA datoB datoF datoK datoL datoS datoA datoB datoF datoK datoL datoS datoX datoE RAM RAM RAM RAM datoX datoX datoE datoE
br.PeekChar() Verifica SENZA spostare il puntatore nel file, cosa c’è oltre il dato scelto. Se non c’è più nulla, quindi il file è finito, restituisce -1 FSNome.Length restituisce la lunghezza in byte dell’intero file. FSNome.Name restituisce il nome, completo di percorso, del file di dati.
Esempio di scrittura **************** (da text) FileStream fsAgg = new FileStream(@“nomefile.dat", FileMode.Append); BinaryWriter BwAgg = new BinaryWriter(fsAgg); BwAgg.Write(TxtCogno.Text); BwAgg.Write(TxtNome.Text); BwAgg.Close(); fsAgg.Close(); ****************
Esempio di lettura (ciclo) **************** (in lista ) FileStream fsL = new FileStream(@“filenome.dat", FileMode.Open); BinaryReader br = new BinaryReader(fsL); // ciclo di scansione o lettura fino a PeekChar= -1 … cioè fino a che è !=-1 LstAmici.Items.Clear(); while (br.PeekChar()!=-1) { LstAmici.Items.Add(br.ReadString()+ " " + br.ReadString() ); // se non leggo 2 volte estrae 1 stringa per volta } br.Close(); fsL.Close(); ****************
Esempio di lettura 1 per volta (testo prima se ce ne sono ancora) **************** (possono esserci strategie diverse, questa è 1 ) FileStream fsL = new FileStream(@“noemfile.dat", FileMode.Open ); BinaryReader br = new BinaryReader(fsL); if (br.PeekChar() != -1) { TxtCogno.Text = br.ReadString(); TxtNome.Text = br.ReadString(); TxtPosiz.Text = Convert.ToString(fsL.Position); } else BtnAvanti.Text = "Finiti!!"; ****************