Avatar billede driis Nybegynder
28. marts 2003 - 12:27 Der er 12 kommentarer og
1 løsning

At skrive en linje til toppen af en fil.

Jeg har behov for at kunne tilføje en linje i toppen af en fil. Som udgangspunkt er der tale om ASCII tekst, men jeg vil også gerne vide hvordan det gøres, hvis der var tale om en datafil (ikke ASCII).

Jeg kunne selvfølgelig læse hele filen, så skrive min linje, der skal tilføjes og derefter skrive resten af filen igen - men der må da være en nemmere (hurtigere) metode ?
Avatar billede arne_v Ekspert
28. marts 2003 - 12:29 #1
Nej.

Generelt kan det ikke lade sig gøre at "sætte ind" i en fil.

Beklager.
Avatar billede arne_v Ekspert
28. marts 2003 - 12:31 #2
Husk på at en fil består af klumper af en eller anden størrelse
(typisk 512/1024/2048/4096 bytes). Fil meta information indeholder
oplysninger om hvilke klumper en fil består af. Det kan ikke lade
sig gøre at sætte et vilkårligt antal bytes ind i den første klump
uden at skubbe rundt på resten af data.
Avatar billede arne_v Ekspert
28. marts 2003 - 12:33 #3
Enkelte operativ-systemer har fil-systemer hvor man har fil-typer
med et logisk record niveau og et fysiske record niveay, hvor man godt
kan ligge nyt data ind til sidst som en fysisk record, men at den logiske
record bliver sat ind først.

Men standard DOS/Windows og Unix/Linux fil-systemer har ikke dette.
Avatar billede erikjacobsen Ekspert
28. marts 2003 - 12:41 #4
Du er bedre tjent med at skrive linien i bunden af filen, og læse den i omvendt rækkefølge
Avatar billede segmose Nybegynder
28. marts 2003 - 13:05 #5
Hvis du ved hvor meget det fylder det du vil skrive ind bagefter kunne du jo afsætte plads til det i filen og så overskrive de tomme positioner bagefter.

Hvis filen ikke er så stor så bare genskriv den.

Hvis det er super vigtigt så find ud af hvordan dit OS lagre filer og "overtal" det til at sætte en block med dine nye data ind forrest, dette er dog en ekstrem løsninger der ikke er særlig portable.
Avatar billede arne_v Ekspert
28. marts 2003 - 13:08 #6
Det er heller ikke altid muligt. Hvis fil systemet kun tillader
klumper af fast størrelse og det man vil skrive ikke har den
størrelse.
Avatar billede segmose Nybegynder
28. marts 2003 - 13:17 #7
Det er rigtigt, men jeg har også gjort en masse andre antagelser om det driis vil skrive:

ved at sætte en block ind af fast længde kan man så udfylde resten med space.
at han som bruger overhovedet må gøre det.
at der er system kald i has OS til at gøre, eller skal man virkelig hacke (skrive sin egen disk-I/O).
at han selv har lavet filen i første omgang.
etc.
Avatar billede driis Nybegynder
28. marts 2003 - 13:36 #8
OK - Hvis jeg så vælger at skrive til bunden af filen i stedet - hvordan gør jeg så, hvis jeg f.eks. vil læse de 2 nederste linjer, uden at skulle søge hele filen igennem for at finde ud af, hvor 2. nederste linje begynder ?
Avatar billede driis Nybegynder
28. marts 2003 - 13:39 #9
... jeg bruger som udgangspunkt fstream biblioteket, men jeg er åben for andre muligheder, hvis det gør det nemmere.
Avatar billede arne_v Ekspert
28. marts 2003 - 15:00 #10
Hvis du skal finde de 2 sidste linier i filen læser du en
klump fra byte sidst-X til byte sidst, hvor du er sikker
på at X er stor nok til at indeholde de 2 linier.

Og så scanner du baglæns i filen efter linie-separator (LF, CR LF eller CR
alt afhængig af hvilket system du kører på) og lokaliserer de
sidste 2 linier.
Avatar billede arne_v Ekspert
28. marts 2003 - 15:02 #11
For et halvt års tid siden lavede jeg følgende lille C program
(altså C med stdio ikke C++ og *stream):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stat.h>

#define N 5120

static char retbuf[1024];

char *get_last_line(char *fnm)
{
  FILE *fp;
  struct stat st;
  char tmpbuf[N];
  int ix,len,bufix;
  stat(fnm, &st);
  len=st.st_size<N?st.st_size:N;
  ix=st.st_size-len;
  fp=fopen(fnm,"rb");
  fseek(fp,ix,SEEK_SET);
  fread(tmpbuf,len,1,fp);
  fclose(fp);
  bufix=len-1;
  while((tmpbuf[bufix]!='\n')&&(bufix>0)) bufix--;
  memcpy(retbuf,tmpbuf+bufix,len-bufix);
  retbuf[len-bufix]='\0';
  return retbuf;
}

int main(int argc,char *argv[])
{
  printf("last line is = %s\n", get_last_line("z.log"));
  exit(0);
}

som læser den sidste linie.
Avatar billede arne_v Ekspert
28. marts 2003 - 15:04 #12
Noget tilsvarende må også kunne laves med *stream.

NB: Bemærk at ovenstående kode er ikke helt portabelt. Åbne en
    fil binært og lede efter linie separator bør virke på både
    DOS/Windows og Unix/Linux, men der er fil-systemer hvor det
    ikke virker.
Avatar billede driis Nybegynder
30. marts 2003 - 15:56 #13
Jeg bruger noget lignende arne_v's eksempel. Tak for hjælpen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester