c - metatogger - tagger automatiquement ses mp3




Que fait réellement l'ouverture d'un fichier? (6)

Dans tous les langages de programmation (que j'utilise au moins), vous devez ouvrir un fichier avant de pouvoir le lire ou l'écrire.

Mais que fait réellement cette opération ouverte?

Les pages de manuel pour des fonctions typiques ne vous disent pas autre chose que cela "ouvre un fichier en lecture / écriture":

http://www.cplusplus.com/reference/cstdio/fopen/

https://docs.python.org/3/library/functions.html#open

De toute évidence, grâce à l'utilisation de la fonction, vous pouvez constater que cela implique la création d'un type d'objet facilitant l'accès à un fichier.

Une autre façon de le dire serait que, si je mettais en place une fonction open , que faudrait-il faire sous Linux?


Au cœur de celui-ci lors de l’ouverture pour la lecture, il n’ya vraiment pas besoin de fantaisie. Il suffit de vérifier que le fichier existe et que l'application dispose de suffisamment de privilèges pour le lire et créer un descripteur sur lequel vous pouvez émettre des commandes de lecture pour le fichier.

C'est sur ces commandes que la lecture réelle sera envoyée.

Le système d'exploitation prend souvent une longueur d'avance sur la lecture en lançant une opération de lecture pour remplir la mémoire tampon associée au descripteur. Ensuite, lorsque vous effectuez la lecture, il peut renvoyer immédiatement le contenu de la mémoire tampon plutôt que de devoir attendre sur le disque IO.

Pour ouvrir un nouveau fichier en écriture, le système d'exploitation devra ajouter une entrée dans le répertoire du nouveau fichier (actuellement vide). Et encore une poignée est créée sur laquelle vous pouvez émettre les commandes d'écriture.


Comptabilité, principalement. Cela inclut diverses vérifications telles que "Le fichier existe-t-il?" et "Ai-je les autorisations pour ouvrir ce fichier en écriture?".

Mais tout cela concerne le noyau - à moins que vous n'utilisiez votre propre système d'exploitation jouet, il n'y a pas grand chose à explorer (si vous y êtes, amusez-vous - c'est une excellente expérience d'apprentissage). Bien sûr, vous devez tout de même connaître tous les codes d'erreur possibles que vous pouvez recevoir lors de l'ouverture d'un fichier, afin de pouvoir les gérer correctement - mais ce sont généralement de belles petites abstractions.

La partie la plus importante au niveau du code est qu’elle vous donne une poignée pour le fichier ouvert, que vous utilisez pour toutes les autres opérations que vous effectuez avec un fichier. Ne pourriez-vous pas utiliser le nom de fichier au lieu de ce descripteur arbitraire? Bien sûr, mais utiliser une poignée vous procure certains avantages:

  • Le système peut garder une trace de tous les fichiers actuellement ouverts et empêcher leur suppression (par exemple).
  • Les systèmes d’exploitation modernes sont construits autour de poignées - il existe une multitude de choses utiles que vous pouvez faire avec les poignées, et tous les types de poignées se comportent de manière presque identique. Par exemple, lorsqu'une opération d'E / S asynchrone se termine sur un descripteur de fichier Windows, celui-ci est signalé. Cela vous permet de bloquer le traitement jusqu'à ce qu'il soit signalé ou de terminer l'opération de manière totalement asynchrone. Attendre un descripteur de fichier équivaut exactement à attendre un descripteur de fil (signalé, par exemple, lorsque le fil se termine), un descripteur de processus (à nouveau, signalé à la fin du processus) ou un socket (à la fin de certaines opérations asynchrones). De manière tout aussi importante, les descripteurs sont la propriété de leurs processus respectifs. Ainsi, lorsqu'un processus est arrêté de manière inattendue (ou que l'application est mal écrite), le système d'exploitation sait quels traitements il peut libérer.
  • La plupart des opérations sont positionnelles - vous read partir de la dernière position de votre fichier. En utilisant un descripteur pour identifier une "ouverture" particulière d'un fichier, vous pouvez avoir plusieurs descripteurs simultanés dans le même fichier, chacun lisant à partir de leurs propres emplacements. D'une certaine manière, le handle agit comme une fenêtre mobile dans le fichier (et un moyen d'émettre des requêtes d'E / S asynchrones, qui sont très pratiques).
  • Les poignées sont beaucoup plus petites que les noms de fichiers. Un handle est généralement la taille d'un pointeur, généralement 4 ou 8 octets. D'autre part, les noms de fichiers peuvent avoir des centaines d'octets.
  • Les poignées permettent au système d'exploitation de déplacer le fichier, même si les applications l'ont ouvert - la poignée est toujours valide et pointe toujours sur le même fichier, même si le nom du fichier a été modifié.

Vous pouvez également effectuer d'autres astuces (par exemple, partager des descripteurs entre processus pour disposer d'un canal de communication sans utiliser de fichier physique; sur les systèmes unix, les fichiers sont également utilisés pour les périphériques et divers autres canaux virtuels, ce qui n'est pas strictement nécessaire. ), mais ils ne sont pas vraiment liés à l'opération d' open elle-même, je ne vais donc pas approfondir cela.


En gros, un appel à ouvrir doit rechercher le fichier, puis enregistrer ce dont il a besoin pour que les opérations d'E / S ultérieur puissent le retrouver. C'est assez vague, mais ce sera le cas pour tous les systèmes d'exploitation auxquels je peux penser immédiatement. Les spécificités varient d'une plateforme à l'autre. De nombreuses réponses évoquent déjà les systèmes d’exploitation de bureau modernes. J'ai fait un peu de programmation sur CP / M, je vais donc offrir mes connaissances sur son fonctionnement sur CP / M (MS-DOS fonctionne probablement de la même manière, mais pour des raisons de sécurité, ce n'est pas normalement le cas aujourd'hui ).

Sur CP / M, vous avez un élément appelé FCB (comme vous l'avez mentionné, vous pouvez l'appeler une structure; il s'agit en réalité d'une zone contiguë de 35 octets dans la RAM contenant divers champs). Le FCB a des champs pour écrire le nom du fichier et un entier (4 bits) identifiant le lecteur de disque. Ensuite, lorsque vous appelez le fichier ouvert du noyau, vous passez un pointeur sur cette structure en la plaçant dans l'un des registres de la CPU. Quelque temps plus tard, le système d'exploitation revient avec la structure légèrement modifiée. Quelle que soit l'entrée / sortie que vous fassiez sur ce fichier, vous passez un pointeur sur cette structure à l'appel système.

Que fait CP / M avec ce FCB? Il réserve certains champs pour son propre usage et les utilise pour garder une trace du fichier. Vous feriez donc mieux de ne pas les toucher de l'intérieur de votre programme. L'opération Open File recherche dans la table au début du disque un fichier portant le même nom que ce qui se trouve dans le FCB (le caractère générique '?' Correspond à n'importe quel caractère). S'il trouve un fichier, il copie certaines informations dans le FCB, y compris le ou les emplacements physiques du fichier sur le disque, de sorte que les appels d'E / S ultérieurs appellent finalement le BIOS qui peut éventuellement transférer ces emplacements au pilote de disque. A ce niveau, les spécificités varient.


En termes simples, lorsque vous ouvrez un fichier, vous demandez réellement au système d’exploitation de charger le fichier souhaité (copier le contenu du fichier) à partir de la mémoire secondaire vers la RAM pour le traitement. Et la raison derrière ceci (Chargement d'un fichier) est parce que vous ne pouvez pas traiter le fichier directement à partir du disque dur en raison de sa vitesse extrêmement lente comparée à celle de Ram.

La commande open va générer un appel système qui copie à son tour le contenu du fichier du stockage secondaire (disque dur) vers le stockage principal (Ram).

Et nous "fermons" un fichier parce que le contenu modifié du fichier doit être reflété dans le fichier d'origine qui se trouve sur le disque dur. :)

J'espère que ça t'as aidé.


Tout dépend du système d'exploitation, de ce qui se passe exactement lorsque vous ouvrez un fichier. Ci-dessous, je décris ce qui se passe sous Linux, car cela vous donne une idée de ce qui se passe lorsque vous ouvrez un fichier. Vous pouvez vérifier le code source si vous souhaitez plus de détails. Je ne couvre pas les autorisations car cela rendrait la réponse trop longue.

Sous Linux, chaque fichier est reconnu par une structure appelée inode . Chaque structure a un numéro unique et chaque fichier ne reçoit qu'un seul numéro d'inode. Cette structure stocke les métadonnées d'un fichier, par exemple la taille du fichier, les autorisations sur le fichier, les horodatages et le pointeur sur les blocs de disque, mais pas le nom du fichier lui-même. Chaque fichier (et répertoire) contient une entrée de nom de fichier et le numéro d'inode à rechercher. Lorsque vous ouvrez un fichier, en supposant que vous disposiez des autorisations appropriées, un descripteur de fichier est créé à l'aide du numéro d'inode unique associé au nom de fichier. Comme de nombreux processus / applications peuvent pointer vers le même fichier, inode possède un champ de lien qui conserve le nombre total de liens vers le fichier. Si un fichier est présent dans un répertoire, son nombre de liens est égal à un. S'il possède un lien physique, son nombre de liens sera égal à deux et si un fichier est ouvert par un processus, le nombre de liens est incrémenté de 1.


Tout système de fichiers ou système d'exploitation dont vous souhaitez parler me convient parfaitement. Agréable!

Sur un ZX Spectrum, l’initialisation d’une commande LOAD place le système dans une boucle serrée, lisant la ligne Audio In.

Le début des données est indiqué par une tonalité constante, suivie d'une séquence d'impulsions longues / courtes, où une impulsion courte correspond à un 0 binaire et une plus longue au 1 binaire ( https://en.wikipedia.org/wiki/ZX_Spectrum_software ). La boucle de charge serrée rassemble des bits jusqu'à remplir un octet (8 bits), la stocke en mémoire, augmente le pointeur de mémoire, puis revient en boucle pour rechercher d'autres bits.

En règle générale, la première chose que lirait un chargeur est un en- tête de format fixe et court, indiquant au moins le nombre d’octets à attendre, et éventuellement des informations supplémentaires telles que le nom, le type et l’adresse de chargement du fichier. Après avoir lu ce court en-tête, le programme pourrait décider de continuer le chargement de la majeure partie des données ou de quitter la routine de chargement et d’afficher un message approprié pour l’utilisateur.

Un état de fin de fichier peut être reconnu en recevant autant d'octets que prévu (soit un nombre d'octets fixe, câblé dans le logiciel, ou un numéro de variable comme indiqué dans un en-tête). Une erreur était générée si la boucle de chargement ne recevait pas d'impulsion dans la plage de fréquences attendue pendant un certain temps.

Un peu de fond sur cette réponse

La procédure décrite charge les données d'une bande audio normale - d'où la nécessité de balayer l'entrée audio (connectée avec une prise standard à des magnétophones). Techniquement, une commande LOAD revient à open un fichier - mais elle est physiquement liée au chargement du fichier. En effet, le magnétophone n'est pas contrôlé par l'ordinateur et vous ne pouvez pas (correctement) ouvrir un fichier sans le charger.

La "boucle étroite" est mentionnée car (1) le processeur, un Z80-A (si la mémoire le permet), était très lent: 3,5 MHz, et (2) le spectre n'avait pas d'horloge interne! Cela signifie qu’il devait tenir précisément le compte des états T (temps d’instruction) pour chaque. Célibataire. instruction. à l'intérieur de cette boucle, juste pour maintenir la synchronisation précise des bips sonores.
Heureusement, cette faible vitesse du processeur présente l’avantage de pouvoir calculer le nombre de cycles sur un morceau de papier, et donc le temps réel qu’ils prendraient.





linux