[RESOLU] Ecriture SD Bas en Haut

Bonjour,

Dans le cadre d'un TFE je dois enregistrer les actions sur mon système dans un fichier TXT via carte SD (ethernet Shield) puis afficher les plus récentes en premières sur une page HTML.
Mais mon fichier s'enregistre/se lit du plus ancien au plus récent et non l'inverse.

Ma question, comment faire pour écrire/lire mon fichier TXT du plus récent au plus ancien sachant que le texte inscrit dans la carte SD n'a pas toujours la même taille (nbr de caractère).

Carte Arduino MEGA avec IDE 1.0.5 || 1.6.1

#include <SD.h>
#include <SPI.h>
byte byteRead;

File myFile;
String SDSAVE;
int i;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  pinMode(53, OUTPUT);
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  if (SD.exists("Alarme.txt")) SD.remove("Alarme.txt");
  
  myFile = SD.open("Alarme.txt", FILE_WRITE);
  if (myFile) {
    Serial.println("Fichier Ouvert");
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening");
  }
  myFile.close();
}

void loop()
{ if (Serial.available())
  { byteRead = Serial.read();
    if(byteRead =='r')
    { myFile = SD.open("Alarme.txt", FILE_READ);
      if (myFile) { while (myFile.available()) Serial.write(myFile.read());
                    myFile.close();
                  } 
        else { Serial.println("error opening FILE"); }
    }
    else if (byteRead == 'w'){i++;Write_SD("J'AI ECRIT LE TEXTE ");Write_SD(String(i));Write_SD(" fois");Write_SD("
");}
  }	
}

 void Write_SD(String information)
 { SDSAVE += information;
    
   if(information == "
") { myFile = SD.open("Alarme.txt", FILE_WRITE);
                                if (myFile) 
                                { 
                                  myFile.println(SDSAVE);
                                  myFile.close();
                                  SDSAVE="";
                                  Serial.println("Ecriture dans le fichier");
                                }
                              }
 }

PS : Autre question, peut-on être client et serveur avec le shield ETHERNET(car je souhaite récupérer l'heure via serveur ntc et l'afficher sur mon serveur via le même arduino)

Quand tu ouvres le fichier, le pointeur de lecture est par défaut positionné sur son premier caractère.

Il faut mesurer la taille de fichier et sauter à la fin, l'idéal serait de formater des enregistrements de taille fixe sinon il faudra relire plusieurs dernières lignes et trier.

Oui, le shield ethnernet fait client et serveur. Il y a des exemples avec.

Cela devrait t'amener à te poser des questions sur ta façon de stocker les données sur ta carte.
Peut-être devrais-tu stocker sa taille au début de chaque enregistrement. Tu pourrais ainsi te déplacer rapidement dans ton fichier d'enregistrement en enregistrement au lieu de devoir le lire caractère par caractère.

Mais en enregistrant la position de chaque début de ligne, je vais devoir avoir un grand nombre de donnée a traité sachant que le texte enregistré n'est rarement de même taille que son prédécesseur.
J'aurai voulu trouver une solution pour qu'a chaque écriture il retourne en début de fichier et écrit devant l'autre texte.

Bonjour,

Ce que tu demandes est difficile à réaliser, car "écrire au début du fichier" =

  1. Ecrire la dernière ligne dans un nouveau fichier
  2. Recopier le contenu de l'ancien fichier dans le nouveau
  3. Renommer le nouveau fichier et supprimer l'ancien

Si tu fixes une taille maximum par ligne, et si tu écris des blocs de taille identique (le texte d'une ligne est alors complété par des blancs ou tronqué à la taille maximum), c'est plus facile de se déplacer au dernier bloc, et de remonter au bloc précédent via les opérations telles fseek().

logansquare:
Mais en enregistrant la position de chaque début de ligne, je vais devoir avoir un grand nombre de donnée a traité sachant que le texte enregistré n'est rarement de même taille que son prédécesseur.
J'aurai voulu trouver une solution pour qu'a chaque écriture il retourne en début de fichier et écrit devant l'autre texte.

bonjour
la solution la moins penible est surement de travailler sur des enregistrement de taille fixe et de dimensionner ton fichier en fonction de l'estimation de volume.
il suffit "ensuite" de sauvegarder le nombre d'enregistrement ecris et de lire de cet enregistrement (le plus recent en chronologie) jusqu'à la fin du fichier (le plus ancien en chronologie).
ce n'est pas tres beau , mais c'est efficace

jusqu'au dernier inscrit

Artouste:
bonjour
la solution la moins penible est surement de travailler sur des enregistrement de taille fixe et de dimensionner ton fichier en fonction de l'estimation de volume.
il suffit "ensuite" de sauvegarder le nombre d'enregistrement ecris et de lire de cet enregistrement (le plus recent en chronologie) jusqu'à la fin du fichier (le plus ancien en chronologie).
ce n'est pas tres beau , mais c'est efficace

J'ai fini par suivre ton idée et comme tu le dis c'est pas très beau mais efficace

#include <SD.h>
#include <SPI.h>
byte byteRead;

File myFile;
String SDSAVE;
int i;
int TAILLEDUFICHIER;
int TAILLEMAXIMUM = 100;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  pinMode(53, OUTPUT);
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  if (SD.exists("Alarme.txt")) SD.remove("Alarme.txt");
  
  myFile = SD.open("Alarme.txt", FILE_WRITE);
  if (myFile) {
    Serial.println("Fichier Ouvert");
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening");
  }
  myFile.close();
}

void loop()
{ if (Serial.available())
  { byteRead = Serial.read();
    if(byteRead =='r')
    { myFile = SD.open("Alarme.txt", FILE_READ);
      if (myFile) { while (myFile.available()) Serial.write(myFile.read());
                    myFile.close();
                  } 
        else { Serial.println("error opening FILE"); }
    }
    
    if(byteRead =='v')
    { myFile = SD.open("Alarme.txt", FILE_READ);
      Serial.println("Fichier ouvert");
      if (myFile) { int POSITIONCOURANTE = TAILLEDUFICHIER;
                    myFile.seek(TAILLEDUFICHIER);
                    while (POSITIONCOURANTE>0){
                      POSITIONCOURANTE -= 100;
                      myFile.seek(POSITIONCOURANTE);
                      while (myFile.position()<POSITIONCOURANTE+100) Serial.write(myFile.read()); } 
                    myFile.close();
                  } 
        else { Serial.println("ERROR REVERSE"); }
    }
    if(byteRead =='p')
    { myFile.seek(71);
      Write_SD("Voici un long texte pour savoir differencier les longs des courts textes enfin bref");Write_SD("
"); // ce texte fait 100 caractère (C'est le maximum) + 5 caractère (balise HTML)
    }
    else if (byteRead == 'w'){i++;Write_SD("J'AI ECRIT LE TEXTE ");Write_SD(String(i));Write_SD(" fois");Write_SD("
");} // texte de minimum 26 caractères (sachant que i est un int) + 5 caractère (balise HTML)
  }	
}


 void Write_SD(String information)
 { SDSAVE += information;
   int taille;
   if(information == "
") { myFile = SD.open("Alarme.txt", FILE_WRITE);
                                if (myFile) 
                                { taille = SDSAVE.length()+2;          // +2 pour le \n généré par le println
                                  myFile.print(SDSAVE);
                                  //Serial.print(taille);
                                  while(taille<100) {myFile.print(" ");taille++;}
                                  myFile.println();
                                  TAILLEDUFICHIER = myFile.position();
                                  myFile.close();
                                  SDSAVE="";
                                  Serial.println("Ecriture dans le fichier");
                                }
                              }
 }

PS je sais mes codes ne sont pas forcement clair

Ce que tu demandes est difficile à réaliser, car "écrire au début du fichier" =

  1. Ecrire la dernière ligne dans un nouveau fichier
  2. Recopier le contenu de l'ancien fichier dans le nouveau
  3. Renommer le nouveau fichier et supprimer l'ancien

Ceci aurai été plus beau mais je ne peux pas me permettre de perdre de temps à d'effectuer l'ouverture/fermeture 2x de suite

Merci à Christian_R, fdufnews, XavierMiller && Artouste pour vos post et pour votre aide