Quale parte del codice dovrebbe riavvolgere un puntatore di file?

1

Se avevi una funzione che prendeva un gestore in un file e poi eseguiva alcune azioni che spostavano il puntatore, ti aspetti che rimetta il puntatore al termine? Inoltre, ti aspetteresti generalmente che riavvolgesse all'inizio prima che iniziasse il suo lavoro?

def hash_contents(fp):
    original_pos = fp.tell()
    fp.seek(0)
    # do hashing / whatever
    fp.seek(original_pos)

Mi sono guardato un po 'intorno per vedere quali sono le ipotesi più comuni, ma non sono sicuro di quale sia una buona regola da seguire. Ad esempio, shutil.copyfileobj copia dalla posizione in cui è stato avviato il file e poi consuma fino alla fine.

Quali sono i pro / contro e quali sono le regole generali da seguire quando si progettano questi tipi di funzioni?

Questa è in realtà una sottocategoria di qualcosa che stavo chiedendo a StackOverflow ( Preferisci byte o byte per l'interfaccia interna in Python? ) che sembra davvero più adatto qui.

    
posta Aidan Kane 19.02.2015 - 11:27
fonte

3 risposte

2

Nella maggior parte dei casi, è previsto che qualsiasi funzione che agisce su un file sposterà il puntatore del file. Ci sono casi rari in cui ho usato le funzioni per dare un'occhiata al file, che prevedeva di lasciare il puntatore del file così come è stato trovato. In tutti gli altri casi, mi aspetto che il puntatore del file si sposti come un effetto collaterale della funzione.

Le funzioni che non spostano il puntatore del file potrebbero rompere le cose gravemente nella maggior parte dei casi in cui accedo ai file come oggetti. Tuttavia, potrei aspettarmi che una funzione abbia il contenuto del file per lasciare il puntatore del file nella sua posizione originale. Tuttavia, ci sono casi in cui desidero ricevere X byte dall'hash della posizione corrente e potrebbe non interessare a dove si spostava il puntatore. Mi aspetterei che il comportamento sia specificato per tale funzione.

Mentre gli effetti collaterali delle chiamate di funzione sono generalmente scoraggiati, questo è un caso in cui sono previsti. A meno che non si abbia a che fare con codice che ha motivo di accedere in modo casuale (database di qualche tipo), l'aspettativa è che le chiamate ripetute di una funzione avanzeranno attraverso il file.

Il codice del tipo di database potrebbe contenere un codice che sposta la posizione nella posizione dei dati e un codice diverso per leggere tali dati. Spesso l'indice e i file di dati sono separati, quindi potrebbe essere opportuno eseguire letture ripetute dopo un riposizionamento.

In un caso, mi aspettavo che una lettura tracciasse dove si trovava il puntatore del file, in modo che una successiva scrittura sovrascriverebbe i dati appena letti. Mentre questo era il comportamento documentato, ha fallito drasticamente. La scrittura ha riavvolto il file e sembrava non aver scritto nulla. Il risultato è stato un ciclo in cui i dati sono stati letti nella posizione richiesta e sovrascritta, seguita da un riavvolgimento del file. Ho cambiato il codice per leggere da un file e scrivere tutti i dati nel nuovo file con le modifiche richieste applicate.

    
risposta data 20.02.2015 - 06:20
fonte
4

Cambiare lo stato di un handle di file è un effetto collaterale così pesante che vorrei che fosse molto documentato nell'interfaccia esattamente quale fosse il metodo, e quindi non importa in che modo si decide.

    
risposta data 19.02.2015 - 11:29
fonte
2

Guardando dal punto di vista di altri linguaggi, sia in Java che in C ++ molte librerie e interfacce accettano un InputStream / istream generico come parametro quando devono leggere qualcosa (e quindi per leggere un file, si passa FileInputStream / ifstream).

Oltre al vantaggio di poter leggere da altre fonti di input rispetto ai file, i flussi di input sono sempre considerati come un solo modo, il che rende immediatamente chiaro al programmatore che non dovresti aspettarti che riavvolgi il puntatore del file.

    
risposta data 20.02.2015 - 14:31
fonte

Leggi altre domande sui tag