2012-08-05 6 views
15

Questa domanda penso sia abbastanza tecnica per S/O, e probabilmente troppo orientata alla programmazione per Android. Sono incuriosito da come i file vengono gestiti in Android (o Java o Linux, a seconda dei casi), dal momento che ho fatto qualcosa con il mio nuovo smartphone e sarei curioso di sapere come è successo.Perché posso spostare correttamente un file in Linux mentre viene scritto?

Stavo trasferendo un file dal mio portatile al mio telefono Android, tramite Bluetooth. Ho visto il nuovo file nel file explorer, supponevo che fosse completamente trasferito, quindi lo ho spostato da /sdcard/bluetooth a /sdcard/torrents. Dopo averlo fatto, ho notato che era ancora in fase di trasferimento. Con mia sorpresa, è stato completato con successo, confermato con un'icona di notifica nel telefono e con un controllo MD5 manuale su entrambi i lati. Nella maggior parte dei sistemi, lo spostamento del file avrebbe causato un arresto anomalo.

Qual è il motivo di questo trasferimento riuscito? Sono consapevole del fatto che, in generale, il percorso del file è separato dal percorso del file sul file system (in questo caso, una scheda SD). Immagino che l'app Bluetooth abbia aperto un handle per il file e quando ho spostato il file, una tabella di "file aperti" è stata aggiornata con un nuovo percorso. Questa caratteristica è generalmente vera per qualsiasi sistema Linux? Posso fare un mv su un file in fase di scrittura e aspettarmi che la copia, nella sua nuova posizione, sia corretta?

+0

file Perché sarebbe in movimento tra i due sistemi di file diversi causano un crash per cominciare? I file stessi sono kludges di dati binari; il file system rappresenta solo il modo in cui il mazzo di dati viene memorizzato, rappresentato e rimosso. – Makoto

+1

Non è prevedibile che lo spostamento di un file in sé non causi un arresto anomalo, ma utilizzando 'mv' su un file _ mentre è ancora in fase di scrittura su_ probabilmente (poiché in generale un sistema che scrive su un file dovrebbe essere in grado di assumere che il file rimane nella stessa posizione dall'apertura di scrittura alla chiusura di scrittura). Sto cercando di capire se quest'ultimo caso è vero per tutti i sistemi Linux (o Java, o Android). Punti extra scout/brownie per chiunque possa spiegare perché questo succede! – halfer

risposta

31

Quando si sposta un file all'interno dello stesso filesystem, il file stesso (il inode) non viene spostato a tutti. L'unica cosa che cambia sono le voci della directory in quel filesystem. (La chiamata di sistema invocata da mv in questo caso è rename(2) - controllare che la pagina per ulteriori informazioni e le restrizioni.)

Quando un processo si apre un file, il nome del file viene passato al sistema operativo per indicare quale file si intende, ma la il descrittore di file che si ottiene non è collegato a tale nome (non è possibile recuperare un nome file da esso) – è collegato all'inode.
Dal momento che l'inode rimane invariato quando si rinomina un file (all'interno dello stesso file system), i processi che l'hanno aperta può tranquillamente continuare a leggere e scrivere ad esso – nulla è cambiato per loro, la loro descrittore di file è ancora valido e che punta a destra dati.

Stessa cosa se si elimina un file. I processi possono continuare a leggere e scrivere da esso anche se il file non è più raggiungibile tramite qualsiasi voce di directory. (Questo può portare a situazioni confuse in cui df rapporti che il disco è pieno, ma du dice che si sta utilizzando molto meno spazio che df rapporti. I blocchi assegnati ai file cancellati che sono ancora aperte non saranno rilasciati fino a quando quei processi chiudono la loro descrittore di file.)

Se lo mv sposta il file su file system, il comportamento è diverso poiché gli inode sono specifici per ciascun file system. In tal caso, mv copierà effettivamente i dati, creando un nuovo inode (e voce di directory) sul filesystem di destinazione. Quando la copia è finita, il vecchio file è scollegato e rimosso se non ci sono filehandle aperti su di esso, come sopra.
Nel tuo caso, se avessi attraversato il confine del filesystem, avresti un file parziale nella destinazione. E il tuo processo di caricamento scrive felicemente in un file cancellato a cui non puoi accedere facilmente, magari riempiendo quel file system, fino a quando l'upload non ha terminato il punto in cui l'inode sarebbe caduto.

Alcuni messaggi su Unix & Linux che si potrebbe trovare interessanti:

+0

Ottima risposta, grazie Mat. Sì, stavo spostando il file all'interno del file system. Ho sviluppato su sistemi simil-Unix per alcuni anni, ma non ho mai incontrato prima questa abilità; Mi sarei aspettato che avesse sconvolto il processo di scrittura. Roba abbastanza intelligente! – halfer

Problemi correlati