2009-12-25 5 views
3

J'ai une petite question:Comment les fichiers copient-ils au niveau bas?

Par exemple j'utilise la méthode System.IO.File.Copy() de .NET Framework. Cette méthode est un wrapper géré pour la fonction CopyFile() de WinAPI. Mais comment fonctionne la fonction CopyFile? Il interagit avec le firmware du disque dur ou peut-être d'autres opérations sont effectuées via Assembler ou peut-être quelque chose d'autre ...

Comment cela ressemble-t-il du plus haut niveau au plus bas?

Répondre

7

Mieux vaut commencer par le bas et travailler votre chemin vers le haut.

Les unités de disque sont organisées, au niveau le plus bas, en une collection de secteurs, de pistes et de têtes. Les secteurs sont des segments d'une piste, les pistes sont une zone sur les disques elle-même, représentée par la position des têtes lorsque les plateaux tournent en dessous, et la tête est l'élément réel qui lit les données du plateau. Puisque les pistes sont mesurées en fonction de la distance entre une tête et le centre d'un disque, vous pouvez voir comment, en direction du centre du disque, la "longueur" d'une piste est inférieure à une sur le bord extérieur du disque. disque.

Les secteurs sont des morceaux d'une piste, typiquement d'une longueur fixe. Ainsi, une piste intérieure contiendra moins de secteurs qu'une piste extérieure.

Une grande partie de cette géométrie de disque est gérée par les contrôleurs eux-mêmes de nos jours, bien qu'auparavant cette organisation était gérée directement par les systèmes d'exploitation et les pilotes de disque.

L'électronique de lecteur et les pilotes de disque coopèrent pour essayer de représenter le disque sous la forme d'une série séquentielle de blocs de longueur fixe. Donc, vous pouvez voir que si vous avez un lecteur de 10 Mo et que vous utilisez des blocs de disques de 512 octets, alors ce lecteur aura une capacité de 20 480 "blocs".

Cette organisation en blocs est la base sur laquelle tout le reste est construit. Une fois que vous avez cette capacité, vous pouvez indiquer au disque, via le pilote de disque et le contrôleur de disque, d'aller à un bloc spécifique sur le disque, et lire/écrire ce bloc avec de nouvelles données.

Un système de fichiers organise ce tas de blocs dans sa propre structure. Le SF doit déterminer quels blocs sont utilisés et par quels fichiers.

La plupart des systèmes de fichiers ont un emplacement fixe "par où ils commencent", c'est-à-dire, au démarrage, ils peuvent essayer de trouver des informations sur la disposition du disque. Considérons un système de fichiers brut qui ne possède pas de répertoires et qui prend en charge les fichiers comportant 8 lettres et 3 lettres, plus 1 octet d'informations d'état et 2 octets pour le numéro de bloc où le fichier commence sur le disque. Nous pouvons également supposer que le système a une limite stricte de 1024 fichiers. Enfin, il doit savoir quels blocs sur le disque sont utilisés. Pour cela il utilisera 1 bit par bloc.

Cette information est communément appelée «métadonnées du système de fichiers». Quand un disque est "formaté", de nos jours, il s'agit simplement d'écrire de nouvelles métadonnées du système de fichiers. Dans l'ancien temps, il s'agissait d'écrire des marques de secteur et d'autres informations sur les supports magnétiques vierges (communément appelés «format de bas niveau»). Aujourd'hui, la plupart des lecteurs ont déjà un format bas niveau. Pour notre exemple brut, nous devons allouer de l'espace pour le répertoire, et de l'espace pour la "Table des matières", les données qui indiquent quels blocs sont utilisés.

Nous dirons également que le système de fichiers doit commencer au bloc 16, de sorte que le système d'exploitation puisse utiliser les 16 premiers blocs pour, par exemple, un "secteur de démarrage". Donc, au bloc 16, nous devons stocker 14 octets (chaque entrée de fichier) * 1024 (nombre de fichiers) = 12K. Divisez cela par 512 (taille de bloc) est de 24 blocs. Pour notre lecteur de 10 Mo, il y a 20 480 blocs. 20 480/8 (8 bits/octet) est de 2 560 octets/512 = 5 blocs.

Parmi les 20 480 blocs disponibles sur le disque, les métadonnées du système de fichiers sont 29 blocs. Ajouter dans le 16 pour l'OS, que 45 blocs sur les 20,480, laissant 20,435 "blocs libres".

Enfin, chacun des blocs de données réserve les 2 derniers octets pour pointer vers le bloc suivant dans le fichier.

Maintenant, pour lire un fichier, vous recherchez le nom de fichier dans les blocs de répertoire. De là, vous trouvez le décalage du premier bloc de données pour le fichier. Vous avez lu ce bloc de données, récupérez les deux derniers octets. Si ces deux octets sont 00 00, alors c'est la fin du fichier. Sinon, prenez ce numéro, chargez ce bloc de données et continuez jusqu'à ce que tout le fichier soit lu.

Le code du système de fichiers cache les détails des pointeurs à la fin, et charge simplement les blocs dans la mémoire, pour une utilisation par le programme.Si le programme effectue une lecture (buffer, 10000), vous pouvez voir comment cela se traduira par la lecture de plusieurs blocs de données à partir du disque jusqu'à ce que le tampon soit rempli ou que la fin du fichier soit atteinte.

Pour écrire un fichier, le système doit d'abord trouver un espace libre dans le répertoire. Une fois qu'il a cela, il trouve ensuite un bloc libre dans le bitmap TOC. Enfin, il prend les données, écrit l'entrée du répertoire, définit son premier bloc sur le bloc disponible de l'image bitmap, bascule le bit sur le bitmap, puis prend les données et les écrit dans le bon bloc. Le système tamponnera cette information de manière à ce que, idéalement, il ne doive écrire les blocs qu'une seule fois, lorsqu'ils sont pleins. En écrivant les blocs, il continue de consommer des bits de la table des matières et enchaîne les blocs en même temps. Au-delà de cela, une "copie de fichier" est un processus simple, à partir d'un système exploitant le code du système de fichiers et les pilotes de disque. La copie de fichier lit simplement un tampon, le remplit, écrit le tampon.

Le système de fichiers doit gérer toutes les métadonnées, garder trace de l'endroit où vous lisez un fichier ou de l'endroit où vous écrivez. Par exemple, si vous ne lisez que 100 octets à partir d'un fichier, le système aura besoin de lire l'ensemble du datablock de 512 octets, puis de le connaître sur l'octet 101 lorsque vous tenterez de lire 100 octets à partir du fichier.

Aussi, j'espère que c'est évident, c'est une mise en page de système de fichiers très, très grossière, avec beaucoup de problèmes. Mais les principes fondamentaux sont là, et tous les systèmes de fichiers fonctionnent d'une manière similaire, mais les détails varient considérablement (la plupart des systèmes de fichiers modernes n'ont plus de limites strictes, comme un exemple simple).

2

Le framework .NET appelle l'API Windows.

L'API Windows dispose de fonctions de gestion de fichiers sur différents systèmes de fichiers.

Ensuite, cela dépend du système de fichiers en question. Rappelez-vous, ce n'est pas nécessairement un système de fichiers «normal» sur un disque dur; Il pourrait même s'agir d'une extension shell qui émule juste un lecteur et conserve les données dans votre compte gmail, ou autre. Le fait est que les mêmes fonctions de manipulation de fichiers dans l'API Windows sont utilisées comme une abstraction sur de nombreuses couches de données inférieures possibles.

La réponse dépend vraiment du type de système de fichiers qui vous intéresse.

5

Ceci est une question exigeante ou une réponse très longue, mais je suis en train de le faire bref.

Fondamentalement, le .NET Framework encapsule certains appels "natifs", les appels qui sont traités dans les bibliothèques de niveau inférieur. Ces appels de niveau inférieur sont souvent enveloppés dans une logique de tampon pour cacher des choses compliquées comme la synchronisation du contenu du fichier de votre part. Ci-dessous, il y a le niveau natif, qui interagit avec le noyau du système d'exploitation. Le noyau, le cœur de tout système d'exploitation, traduit ensuite vos instructions de haut niveau en quelque chose que votre matériel peut comprendre. Windows et Linux sont par exemple tous les deux utilisant une couche d'abstraction matérielle, un système qui cache des détails spécifiques au matériel derrière une interface générique. L'écriture d'un pilote pour un périphérique spécifique n'est alors que la tâche d'implémenter toutes les méthodes que certains périphériques doivent fournir. Avant que rien ne soit appelé sur votre matériel, le système de fichiers est impliqué, et le système de fichiers lui-même tamponne et cache beaucoup, mais encore une fois de manière transparente, de sorte que vous ne le remarquez même pas. Le dernier élément de la file d'attente d'appel est le périphérique lui-même, et encore une fois, la plupart des périphériques sont conformes à certains standards (comme SATA ou IDE) et peuvent donc être interfacés d'une manière similaire.

J'espère que cette aide :-)

Questions connexes