[Windows] TUTO – [Partie 2] Utilisation du système de fichiers sous Cosmos

Voici une suite au premier tutoriel (mis à jour à la suite de cette deuxième partie, n’hésitez pas à y faire un tour au cas où :P) sur comment créer et lancer sur une machine virtuelle son premier système d’exploitation. Sous forme de console pour l’instant, le système n’est pas pourvu d’un système de fichiers (créer des dossiers/fichiers, se déplacer dans les dossiers, etc.). Nous allons donc ici voir comment faire cela. Faites place au tutoriel !

Logo de Cosmos


Utilisation du système de fichiers

A. Présentation du VFS

Comme défini plus haut, un système de fichiers va vous permettre de créer des fichiers et dossiers depuis votre système d’exploitation et vous déplacer, ouvrir, supprimer ces fichiers, dossiers, etc. Comme pour l’instant l’utilisation de Cosmos ne se fait essentiellement que sur machine virtuelle et non sur un support physique, nous allons utiliser ce qu’on appelle un système de fichiers virtuel (VFS) ou comme Wikipédia le définit : « Une couche d’abstraction au-dessus d’un système de fichiers plus concret ».

B. Utilisation du VFS

Lancez Visual Studio, créez un projet ou ouvrez votre projet Cosmos C#. Rendez-vous maintenant dans le fichier Kernel.cs.

Initialisation

Avant d’utiliser le système de fichiers virtuel, il va falloir l’initialiser depuis la boucle BeforeRun() de votre projet (voir le premier tutoriel à la partie 2B pour plus d’informations). Voici le code à utiliser :

FS = new Sys.FileSystem.CosmosVFS();
Sys.FileSystem.VFS.VFSManager.RegisterVFS(FS);

Il est bon de savoir que le système de fichiers utilisé par Cosmos ressemble à celui de Windows, chaque lecteur a sa propre lettre et le répertoire par défaut est « 0:\ » comme « C:\ » sur Windows.

La variable dossier_actuel sera par défaut définie par :

string dossier_actuel = "0:\\";

Il faut impérativement utiliser une double barre oblique (« \\ ») inversée pour écrire une simple « \ ».

Commande pour créer un fichier
var f = File.Create(dossier_actuel + "\\fichier.txt"); //Créer un fichier pour chemin dossier_actuel\fichier.txt
f.Close();
Commande pour lire un fichier
string texte = File.ReadAllText(dossier_actuel + "\\fichier.txt"); //La variable 'texte' contiendra le texte contenu dans le fichier
Commande pour supprimer un fichier
File.Delete(dossier_actuel + "\\fichier.txt");
Commande pour créer un dossier
FS.CreateDirectory(dossier_actuel + "\\nomdudossier");
Commande pour supprimer un dossier
Directory.Delete(dossier_actuel + "\\dossier", true); // 'true' signifie que le contenu du dossier va être également supprimé
Commande pour se déplacer vers un dossier
if (input.StartsWith("cd ")) //L'utilisateur entre 'cd nomdudossier'
            {
                var newdir = input.Remove(0, 3); //On extrait le nom du dossier

                if (Directory.Exists(dossier_actuel + newdir))
                //On vérifie si le dossier existe.
                {
                    Directory.SetCurrentDirectory(dossier_actuel);
                    dossier_actuel = dossier_actuel + newdir + "\\";
                }
                else
                {
                    Console.WriteLine("Ce dossier n'existe pas !");
                }
            }
Commande pour se déplacer vers un dossier parent (retour)
var dir = FS.GetDirectory(dossier_actuel);
dossier_actuel = dir.mParent.mFullPath;
Commande pour lister les dossiers et fichiers du dossier ouvert
Console.WriteLine("Type\t     Nom");
                foreach (var dir in Directory.GetDirectories(dossier_actuel))
                {
                    Console.WriteLine("<Dossier>\t" + dir);
                }
                foreach (var file in Directory.GetFiles(dossier_actuel))
                {
                    Console.WriteLine("<Fichier>\t" + file);
                }
Commande pour lister les lecteurs disponibles
var vols = FS.GetVolumes();
                Console.WriteLine("Nom\tTaille\tParent");
                foreach (var vol in vols)
                {
                    Console.WriteLine(vol.mName + "\t" + vol.mSize + "\t" + vol.mParent);
                }

Voilà voilà, vous avez pu voir une liste de différentes commandes utiles à la création d’un système d’exploitation, si vous voulez voir l’application réelle de ces commandes, vous pouvez aller voir la méthode InterpredCMD d’un petit système d’exploitation réalisé par mes soins, où ces commandes y sont inscrites (Ctrl + F pour rechercher dans la page ;) ).

C. Exemple d’implémentation du système de fichiers

Maintenant, depuis votre console, vous pouvez implémenter différentes commandes. Voici un algorithme basique qui va pouvoir interpréter les commandes transmises depuis l’utilisateur (comme depuis le CMD sur Windows) et permettre la création et suppression d’un dossier. Ensuite, à vous d’implémenter vos propres commandes !

using System;
using Sys = Cosmos.System;
using System.IO;
using Cosmos.System.FileSystem;
// Ceci permet d'importer des références.

namespace Custom_Protocol
{
    public class Kernel : Sys.Kernel
    {
        string dossier_actuel = "0:\\";
        public CosmosVFS FS { get; private set; }

        protected override void BeforeRun()
        //Ceci est le code exécuté avant l'exécution du programme.
        {
            Console.Clear();
            //Permet de nettoyer la console des logs de démarrage.

            //On met le clavier en français
            Sys.KeyboardManager.SetKeyLayout(new Sys.ScanMaps.FR_Standard());

            //Initialisation du système de fichier.
            FS = new Sys.FileSystem.CosmosVFS();
            Sys.FileSystem.VFS.VFSManager.RegisterVFS(FS);
            //Fin de l'initialisation

            Console.WriteLine("Tutoriel de customprotocol.com");
            Console.WriteLine("Cosmos a demarre avec succes.");
            //Ceci permet d'écrire une ligne.
        }

        protected override void Run()
        //Ceci est le code exécuté pendant l'exécution du programme, il se répétera indéfiniment.
        {
            Console.Write("commande> ");
            //Ceci permet d'écrire une ligne ou l'on peut écrire sur la même ligne.
            var input = Console.ReadLine();
            //Ceci est une variable qui permet de lire le texte écrit par l'utilisateur.
            InterpretCMD(input);
            //Ceci permet de lancer la méthode qui va interpréter la commande (input)
        }

        private void InterpretCMD(string input)
        //Ceci est la méthode qui interprète la commande envoyée (d'où le "string input") 
        {

            if (input.StartsWith("dir -c ")) //Si la commande commence par dir -c
            {
                string dir = input.Remove(0, 7); //On extrait la commande
                if (!Directory.Exists(dossier_actuel + dir)) //Si le dossier n'existe pas (! symbole de négation)
                {
                    FS.CreateDirectory(dossier_actuel + dir); //On créer le dossier
                    Console.WriteLine("Dossier cree !");
                }
                else if (Directory.Exists(dossier_actuel + dir)) //Sinon si le dossier existe alors
                {
                    Console.WriteLine("Le dossier existe deja !");
                    Console.WriteLine("Dossier cree !");
                    FS.CreateDirectory(dossier_actuel + dir + "-1"); //On créer tout de même un dossier avec comme nom 'nomdudossier-1'
                }
            }

            else if (input.StartsWith("dir -r ")) //Si la commande commence par dir -r alors
            {
                string dirr = input.Remove(0, 7); //On extrait le nom du dossier de la commande
                if (Directory.Exists(dossier_actuel + dirr)) //Si le dossier existe alors
                {
                    Directory.Delete(dossier_actuel + dirr, true); //On le supprime
                    Console.WriteLine("Le dossier '" + dirr + "' a ete supprime !");
                }
                else //Si il n'existe pas
                {
                    Console.WriteLine("Le dossier '" + dirr + "' n'existe pas !");
                }
            }

            else if (input == "dir -l") //Si la commande est égale à dir -l
            {
                Console.WriteLine("Type\t     Nom");
                foreach (var dir in Directory.GetDirectories(dossier_actuel)) //On récupere tous les dossiers
                {
                    Console.WriteLine("<Dossier>\t" + dir); //On affiche tous les dossiers
                }
            }

            else if (input == "hello")
            { //Si la commande est égale à hello alors
                Console.WriteLine("Bonjour!"); //Afficher "Bonjour!".
            }

            else if (input == "bye")
            { //Sinon si la commande est égale à bye
                Sys.Power.Shutdown(); //Éteindre le système.
            }

            else
            { //Sinon (si la commande n'est ni hello ni bye)
                Console.WriteLine("Erreur : Commande inconnue"); //Afficher la commande est inconnue.
            }

        }
    }
}

3) Conclusion

À travers ce tutoriel, vous avez pu voir comment utiliser un système de fichiers dans votre projet Cosmos. Amusez-vous, développez et partagez votre projet ! Si vous manquez d’inspiration, voici même une page comprenant plusieurs projets sous Cosmos : Cosmos Projects.

D’autres tutoriels à propos de Cosmos arriveront sur Custom Protocol bientôt, si vous avez besoin de quoi que ce soit vous pouvez poser une question en commentaire ou sur la conversation Gitter du projet Cosmos ! ;)