2012-02-07 9 views
21

Sto usando fs.Length, dove fs è un FileStream.Il modo più veloce per leggere la lunghezza del file C#

Si tratta di un'operazione O(1)? Penserei che questo sarebbe solo leggere dalle proprietà del file, al contrario di passare attraverso il file per trovare quando la posizione di ricerca ha raggiunto la fine. Il file che sto cercando di trovare può durare da 1 MB a 4-5 GB.

Tuttavia ho notato che esiste una classe FileInfo, che ha anche una proprietà Length.

Queste due proprietà Length richiedono in teoria la stessa quantità di tempo? Oppure è fs.Length più lento perché deve aprire prima il FileStream?

risposta

30

Il modo naturale per ottenere le dimensioni del file in .NET è la proprietà FileInfo.Length che hai menzionato.

non sono sicuro Stream.Length è più lento (non leggerà l'intero file in ogni caso), ma è sicuramente più naturale da usare FileInfo invece di una FileStream se non avete intenzione di leggere il file.


Ecco un piccolo punto di riferimento in grado di fornire alcuni valori numerici:

private static void Main(string[] args) 
{ 
    string filePath = ...; // Path to 2.5 GB file here 

    Stopwatch z1 = new Stopwatch(); 
    Stopwatch z2 = new Stopwatch(); 

    int count = 10000; 

    z1.Start(); 
    for (int i = 0; i < count; i++) 
    { 
     long length; 
     using (Stream stream = new FileStream(filePath, FileMode.Open)) 
     { 
      length = stream.Length; 
     } 
    } 

    z1.Stop(); 

    z2.Start(); 
    for (int i = 0; i < count; i++) 
    { 
     long length = new FileInfo(filePath).Length; 
    } 

    z2.Stop(); 

    Console.WriteLine(string.Format("Stream: {0}", z1.ElapsedMilliseconds)); 
    Console.WriteLine(string.Format("FileInfo: {0}", z2.ElapsedMilliseconds)); 

    Console.ReadKey(); 
} 

Risultati:

Stream: 886 
FileInfo: 727 
+0

malvagio, grazie per le informazioni sul tempo! – jpints14

+1

Il benchmarking in questo modo potrebbe non essere il modo più efficace di testare una differenza (se ce n'è una). Immagino che i fattori di cache/os del disco giochino un ruolo considerevole nel tenere i tempi bassi. – PaulG

+0

@PaulG Hai ragione. Il benchmarking è ** sempre ** più complicato di quanto sembri. Il benchmark semplice sopra ** solo ** fornisce alcune indicazioni sul risultato effettivo. Siccome non ritorna, diciamo 100000 vs 250, penso che sia possibile concludere che entrambi i metodi non sono troppo diversi_ (in termini di tempo di calcolo). – ken2k

23

Entrambe accedono ai metadati del file system anziché leggere l'intero file. Non so quale sia più efficace necessariamente, come regola generale direi che se si solo si desidera conoscere la lunghezza (e altri metadati), utilizzare FileInfo - mentre se si sta aprendo il file come flusso comunque, utilizzare FileStream.Length.

+0

Grazie signor Skeet! – jpints14

Problemi correlati