...suppongo che ci siano soluzioni più "raffinate", o sbaglio?
A mio modestissimo parere, nel momento in cui usi specifiche funzioni all'uopo preposte, adotti già una metodologia "raffinata". Dunque fra due previste e legittime soluzioni, si pone una duplice questione:
* che tipo di dati ti servono da manipolare successivamente ? Tipo Byte ? Tipo Stringa ?
* è necessaria la velocità nell'apertura del file ?
Avrei bisogno di aprire dei files,
Tenuto conto che devi aprire dei pesantissimi file, la risposta alla seconda domanda mi pare sia positiva. Ebbene da quel che ho potuto sempre notare, l'apertura di un file con il metodo .Load della Classe File, è molto veloce, e ben più veloce della modalità di assunzione dei dati mediante un ciclo dopo aver aperto il file con l'istruzione Open.... For Read.
Ti riporto un test di velocità che ho fatto (i valori temporali sono condizionati dalla capacità del mio PC, ma chiaramente ciò che importa è il confronto fra i tre test) mediante un file di 40 megabyte:
* modalità Open.... For Read + ciclo While...Wend (raccolta dati di tipo Byte):
Public Sub Form_Open()
Dim fl As File
Dim b As Byte
fl = Open "/percorso/del/file" For Read
While Not Eof(fl)
Read #fl, b
Wend
fl.Close
End
ha impiegato 7602 millisecondi;
* modalità File.Load() (raccolta dati tipo Stringa):
Public Sub Form_Open()
Dim s As String
s = File.Load("/percorso/del/file")
End
ha impiegato 451 millisecondi;
* modalità Open.... For Read + sola istruzione Read a lunghezza fissa (raccolta dati tipo Stringa):
Public Sub Form_Open()
Dim fl As File
Dim s As String
fl = Open "/percorso/del/file"
' Lettura a lunghezza "fissa":
Read #fl, s, Stat("/percorso/del/file").Size
fl.Close
End
ha impiegato 31 millisecondi.
Ad ogni modo, puoi agevolmente ottenere valori di tipo Byte da valori a rappresentazione Stringa utilizzando il metodo .FromString() della Classe Byte[]:
Public Sub Form_Open()
Dim fl As File
Dim s As String
Dim bb As Byte[]
fl = Open "/percorso/del/file"
Read #fl, s, Stat("/percorso/del/file").Size
bb = Byte[].FromString(s)
fl.Close
End
Avrei bisogno di ... leggere dei byte a determinate posizioni, modificarli
Se utilizzi l'apertura del file con l'istruzione "Open..." puoi spostarti all'interno del flusso dei dati mediante la funzione Seek #variabile_file, indice_dei_dati .
Esempio:
Public Sub Main()
Dim b As Byte
Dim fl As File
fl = Open "/percorso/del/file" For Read
' Spostiamo il puntatore del flusso al byte num. 9 (ossia il 10°):
Seek #fl, 9
' Leggiamo il 10° byte :
Read #fl, b
fl.Close
Print b
End
Ho trovato in rete diversi esempi di lettura di un array da file, ma nessuno ha funzionato, provo un po' con i tuoi.
Potresti anche utilizzare il metodo ''.Read()'' dei tipi vettoriali (Byte[], Short[], etc...).
Esempio: lettura di dati di tipo Byte da un file di testo e loro inserimento in un vettore di tipo Byte[ ]:
Public Sub Main()
Dim a As Byte[]
Dim fl As File
Dim b As Byte
fl = Open "/percorso/del/file" For Read
' Impostiamo il numero di elementi dei quali il vettore sarà costituito:
a = New Byte[Stat("/percorso/del/file").Size]
a.Read(fl)
fl.Close
' Andiamo a verificare in console:
For Each b In a
Print Chr(b);
Next
End
Ah, ecco dov'era l'inghippo!!!
In rete avevo trovato soluzioni analoghe, ma non veniva detto che dovevo inizializzare l'array con la dimensione specifica....
Comunque ho provato così e sembra funzionare:
Dim myFile As File
Dim aMyArray As Short[]
Dim Dimensione As Long
' apertura file
myFile = Open "/home/michele/earthworm/friuli/data/bud/NI/5373/copy.bin" For Read
Dimensione = Stat("/home/michele/earthworm/friuli/data/bud/NI/5373/copy.bin").Size
aMyArray = New Byte[Dimensione / 2]
aMyArray.Read(myFile)
Close myFile
' modifica valore
aMyArray[0] = &h7927
' apertura file destinazione
myFile = Open "/home/michele/earthworm/friuli/data/bud/NI/5373/copy3.bin" For Create
aMyArray.Write(myFile)
Close myFile
aMyArray.Clear
aMyArray = New Byte[Dimensione / 2]
' verifica scrittura
myFile = Open "/home/michele/earthworm/friuli/data/bud/NI/5373/copy3.bin" For Read
aMyArray.Read(myFile)
Close myFile
Grazie per l'aiuto!
La definizione a priori del numero degli elementi del vettore non è obbligatoria. Tale numero può essere definito implicitamente e successivamente attraverso il suo progressivo incremento mediante il metodo .Add():
Public Sub Button1_Click()
Dim bb As New Byte[]
Dim b As Byte = 99
' Verifica di quanti elementi è attualmente costituito il vettore:
bb.Count
' Aggiungiamo un elemento (sempre avente valore 99) al vettore:
bb.Add(b)
' Verifica di quanti elementi è ora costituito il vettore:
bb.Count
End
Mah, non so dove sbagliavo, che quando cercavo di fare .Add mi metteva errore....
Per usare il metodo .Add(), non si deve dimenticare la parola New:
Dim bb As New Byte[]
bb.Add(99)