/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
fopen med/uden binary?
Fra : Kaare Brandt Peterse~


Dato : 02-03-01 19:20

Hej der!

fopen("foo","wb");

skulle gerne returnere en filestruct saa man kan skrive binaert til filen
'foo'. Men det sker til syneladende ikke. Efter at filen er skrevet, kan
jeg laese det skrevne direkte med less som om det var en tekst
fil. Compileren er g++

Nogle gode ideer? Set noget der ligner? ...

- kaare
--
Kaare Brandt Petersen - tel. +45 28409998 - http://bifrost.netcetera.dk





 
 
Bertel Lund Hansen (02-03-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 02-03-01 19:45

Kaare Brandt Petersen skrev:

>skulle gerne returnere en filestruct saa man kan skrive binaert til filen
>'foo'. Men det sker til syneladende ikke.

Hvad skriver du til filen?


Kaare Brandt Peterse~ (02-03-2001)
Kommentar
Fra : Kaare Brandt Peterse~


Dato : 02-03-01 22:27

On Fri, 2 Mar 2001, Bertel Lund Hansen wrote:

> Kaare Brandt Petersen skrev:
>
> >skulle gerne returnere en filestruct saa man kan skrive binaert til filen
> >'foo'. Men det sker til syneladende ikke.
>
> Hvad skriver du til filen?

tal ... doubles

--
Kaare Brandt Petersen - tel. +45 28409998 - http://bifrost.netcetera.dk





Igor V. Rafienko (02-03-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 02-03-01 22:36

* Kaare Brandt Petersen

[snip]

> > Hvad skriver du til filen?
>
> tal ... doubles


_hvordan_?





ivr
--
Besides, meat tends to run away when possible, or fights. Either
response presents behavioral challenges too complex for any existing
robot.
      -- Stuart Wilkinson, inventor of the "gastrobot"

Igor V. Rafienko (02-03-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 02-03-01 20:01

* Kaare Brandt Petersen

> fopen("foo","wb");
>
> skulle gerne returnere en filestruct saa man kan skrive binaert til
> filen 'foo'.


Hva legger du i "skrive binært"? På noen implementasjoner er det
_ingen_ forskjell mellom "wb" og "w".


> Men det sker til syneladende ikke. Efter at filen er skrevet, kan
> jeg laese det skrevne direkte med less som om det var en tekst fil.
> Compileren er g++


Spørs hva du skriver til filen. (fprintf'er du en "foo", vil du
fread'e en "foo" etterpå)





ivr
--
Besides, meat tends to run away when possible, or fights. Either
response presents behavioral challenges too complex for any existing
robot.
      -- Stuart Wilkinson, inventor of the "gastrobot"

Kaare Brandt Peterse~ (02-03-2001)
Kommentar
Fra : Kaare Brandt Peterse~


Dato : 02-03-01 22:33

On 2 Mar 2001, Igor V. Rafienko wrote:

> * Kaare Brandt Petersen
>
> > fopen("foo","wb");
> >
> > skulle gerne returnere en filestruct saa man kan skrive binaert til
> > filen 'foo'.
>
>
> Hva legger du i "skrive binært"? På noen implementasjoner er det
> _ingen_ forskjell mellom "wb" og "w".

Det ville forklare hvorofr jeg ikke kan se nogen forskel, men det er da
lidt saert. Hvad skulle det fede saa vaere? De filer som tidligere er
stoedt paa, som er saakaldt binaere, har ikke vaeret mulige at laese
direkte - f.eks. filer skrvet fra Java (som her maa vaere mere eller
mindre det samme!)

... finten var at kunne skrive hurtigere fordi
der typisk er 300000 tal der skal skrives og det tager lidt tid som jeg
gerne ville spare.

> > Men det sker til syneladende ikke. Efter at filen er skrevet, kan
> > jeg laese det skrevne direkte med less som om det var en tekst fil.
> > Compileren er g++
>
>
> Spørs hva du skriver til filen. (fprintf'er du en "foo", vil du
> fread'e en "foo" etterpå)

jeg skriver doubles ...

--
Kaare Brandt Petersen - tel. +45 28409998 - http://bifrost.netcetera.dk





Bertel Lund Hansen (02-03-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 02-03-01 22:59

Kaare Brandt Petersen skrev:

>Det ville forklare hvorofr jeg ikke kan se nogen forskel, men det er da
>lidt saert. Hvad skulle det fede saa vaere?

At kontroltegn behandles som alle andre.

>De filer som tidligere er stoedt paa, som er saakaldt binaere, har ikke vaeret mulige at laese direkte

Det har ikke noget at gøre med om de behandles som binære eller
ej. Det har noget at gøre med hvad der skrives til dem.

>... finten var at kunne skrive hurtigere

Det kan du ikke.


Igor V. Rafienko (03-03-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 03-03-01 15:51

* Kaare Brandt Petersen

[snip]

> > Hva legger du i "skrive binært"? På noen implementasjoner er det
> > _ingen_ forskjell mellom "wb" og "w".
>
> Det ville forklare hvorofr jeg ikke kan se nogen forskel, men det er
> da lidt saert. Hvad skulle det fede saa vaere?


Tja, si det: immsvho er det nisseteit å skille mellom vanlige filer
som inneholder forskjellige data fra OS sitt synspunkt: "regular
files" er nettopp det, og det er opp til applikasjonen å tolke
innholdet.


> De filer som tidligere er stoedt paa, som er saakaldt binaere, har
> ikke vaeret mulige at laese direkte - f.eks. filer skrvet fra Java
> (som her maa vaere mere eller mindre det samme!)


Jeg tviler ikke et sekund på at det var mulig å _lese_ dem direkte
(fread fungerer, såsnart permissions er tilstedet). Derimot var det
kanskje vanskelig å _tolke_ hva fread hadde lest?


> ... finten var at kunne skrive hurtigere fordi der typisk er 300000
> tal der skal skrives og det tager lidt tid som jeg gerne ville
> spare.


Hva er målet med å lagre 300000 doubles og hvor ofte skjer det? Det er
mye snillere (mot mennesker) og mer portabelt å ikke lagre
binærrepresentasjonen av objekter direkte, men heller satse på lagring
av tekstlig representasjon (til tross for en viss tap av effektivitet.
Akkurat hvor mye det blir kommer an på hva man bruker for å lese den
tekstlige representasjonen).

[snip]


> > Spørs hva du skriver til filen. (fprintf'er du en "foo", vil du
> > fread'e en "foo" etterpå)
>
> jeg skriver doubles ...


_hvordan_? Man kan bruke

fprintf( stream, "%f", 42.42 );

og

no = 42.42;
fwrite( &no, sizeof( no ), 1UL, stream );

og de gjør faktisk 2 forskjellige ting.





ivr
--
Besides, meat tends to run away when possible, or fights. Either
response presents behavioral challenges too complex for any existing
robot.
      -- Stuart Wilkinson, inventor of the "gastrobot"

Rasmus Paulsen (03-03-2001)
Kommentar
Fra : Rasmus Paulsen


Dato : 03-03-01 16:39


"Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
news:xjvae72hpn5.fsf@ide.ifi.uio.no...
> Hva er målet med å lagre 300000 doubles og hvor ofte skjer det? Det er
> mye snillere (mot mennesker) og mer portabelt å ikke lagre
> binærrepresentasjonen av objekter direkte, men heller satse på lagring
> av tekstlig representasjon (til tross for en viss tap av effektivitet.
> Akkurat hvor mye det blir kommer an på hva man bruker for å lese den
> tekstlige representasjonen).

Hej

Det er i visse tilfaelde ikke unormalt at skulle skrive store maengder
doubles til en fil. Jeg arbejder blandt andet med meget store matricer, som
skal gemmes i ny og næ.

Hvis størrelsen af filen er et stort problem (f.ex. hvis de skal sendes via
nettet), kan man jo overveje at bruge et komprimeringsværktøj (f.ex. zlib)
til at komprimere sine data inden de dumpes til filen. Det kræver dog at
data er af en natur, der gør dem komprimerbare (ikke hvid støj).

Hilsen
Rasmus




Kaare Brandt Peterse~ (05-03-2001)
Kommentar
Fra : Kaare Brandt Peterse~


Dato : 05-03-01 19:02

On Sat, 3 Mar 2001, Rasmus Paulsen wrote:

>
> "Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
> news:xjvae72hpn5.fsf@ide.ifi.uio.no...
> > Hva er målet med å lagre 300000 doubles og hvor ofte skjer det? Det er
> > mye snillere (mot mennesker) og mer portabelt å ikke lagre
> > binærrepresentasjonen av objekter direkte, men heller satse på lagring
> > av tekstlig representasjon (til tross for en viss tap av effektivitet.
> > Akkurat hvor mye det blir kommer an på hva man bruker for å lese den
> > tekstlige representasjonen).
>
> Hej
>
> Det er i visse tilfaelde ikke unormalt at skulle skrive store maengder
> doubles til en fil. Jeg arbejder blandt andet med meget store matricer, som
> skal gemmes i ny og næ.
>

Jupper-dupper. Det er lange filer fra en beregning som skal indlaese af
MATLAB og det tager lidt tid som jeg gerne ville spare - Filerne er typisk
1-3 MB. Finten med at goere det hurtigt er at saa kan man effektivt bruge
MATLAB som grafisk presentation loebende (uden at skulle lave en mex fil
til MATLAB).

Som jeg ahr forstaaet svarene er det umiddelbart _ikke_ muligt at goere
tiden der bruges til at skrive til filen mindre - og saa er finten under
alle omstaendigheder vaek.

--
Kaare Brandt Petersen - tel. +45 28409998 - http://bifrost.netcetera.dk





Soeren Sandmann (05-03-2001)
Kommentar
Fra : Soeren Sandmann


Dato : 05-03-01 21:24

Kaare Brandt Petersen <kaare@netcetera.dk> writes:

> Som jeg ahr forstaaet svarene er det umiddelbart _ikke_ muligt at goere
> tiden der bruges til at skrive til filen mindre - og saa er finten under
> alle omstaendigheder vaek.

Kig på dette program, som bortset fra funktionen drand48() er
ANSI C. Bemærk at det er helt uportabelt; filen "testfil" vil ikke
kunne bruges på andre maskiner end den der genererede den.

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

static void
write_double (FILE *f, double d)
{
if (fwrite (&d, sizeof (double), 1, f) != 1)
{
    perror ("fwrite");
    exit (EXIT_FAILURE);
   }
}

static double
read_double (FILE *f)
{
double d;
if (fread (&d, sizeof (double), 1, f) != 1)
   {
    perror ("fread");
    exit (EXIT_FAILURE);
   }
return d;
}

enum {
N_DOUBLES = 300000
};

static double darray1[N_DOUBLES];
static double darray2[N_DOUBLES];

int
main ()
{
int i;
FILE *f;

for (i = 0; i < N_DOUBLES; i++)
   darray1[i] = 2000 * drand48 ();

f = fopen ("testfil", "wb");
if (f == NULL)
   {
    perror ("fopen");
    exit (EXIT_FAILURE);
   }
for (i = 0; i < N_DOUBLES; i++)
   write_double (f, darray1[i]);
fclose (f);

f = fopen ("testfil", "rb");
if (f == NULL)
   {
    perror ("fopen");
    exit (EXIT_FAILURE);
   }
for (i = 0; i < N_DOUBLES; i++)
   darray2[i] = read_double (f);
fclose (f);

for (i = 0; i < N_DOUBLES; i++)
   if (darray1[i] != darray2[i])
    {
      fprintf (stderr, "darray1[%d] != darray2[%d] (%f != %f)\n",
          i, i, darray1[i], darray2[i]);
      exit (EXIT_FAILURE);
    }
return EXIT_SUCCESS;
}

Lars Blaabjerg (06-03-2001)
Kommentar
Fra : Lars Blaabjerg


Dato : 06-03-01 07:54

"Kaare Brandt Petersen" <kaare@netcetera.dk> wrote in message
news:Pine.LNX.4.21.0103051901520.9150-100000@nidhug.netcetera.dk...
On Sat, 3 Mar 2001, Rasmus Paulsen wrote:
---snip-----
> Som jeg ahr forstaaet svarene er det umiddelbart _ikke_ muligt at goere
> tiden der bruges til at skrive til filen mindre - og saa er finten under
> alle omstaendigheder vaek.

Hvis det er et rent performance issue kan _måden_ hvorpå du læser gøre en
forskel. Jeg husker engang jeg lavede et pascal program der skulle læse en
masse data ind. Jeg vandt _enormt_ meget ved at læse hele dynen på en gang,
istedet for, som en anden foreslog det en double af gangen. Det har
selvfølgelig meget at gøre med hvordan filtilgangen er implementeret i dine
libs. Men prøv (hvis du ikke allerede gør det) at indlæse data'ene på
følgende måde:

double buffer[30000];
FILE* file = fopen("foo","rb");
fread(buffer,sizeof(double),30000,file);
fclose(file);

Dette er selvfølgeligt ikke så portabelt, men hvis dataene er skrevet på
samme måde, burde det virke. Det burde ikke tage lang tid at læse 30000
doubles!

Håber det kunne bruges
Lars







Soeren Sandmann (06-03-2001)
Kommentar
Fra : Soeren Sandmann


Dato : 06-03-01 16:38

"Lars Blaabjerg" <lab@***nospam***ready.dk> writes:

> selvfølgelig meget at gøre med hvordan filtilgangen er implementeret i dine
> libs. Men prøv (hvis du ikke allerede gør det) at indlæse data'ene på

Normalt kan man roligt regne med at standardimplementationerne af
filadgangsfunktionerne er bedre end hvad man selv kan lave med read(),
write() mv.. Standardfunktionernes har normalt buffere som er
tilpasset systemet bedre end man selv kan gøre (i hvert fald bedre end
man selv kan gøre portabelt).

Det gælder imidlertid også generelt at man skal forsøge at skrive så
meget som muligt ad gangen, så det underliggende system har mulighed
for at udnytte bufferne optimalt.

> følgende måde:
>
> double buffer[30000];
> FILE* file = fopen("foo","rb");
> fread(buffer,sizeof(double),30000,file);
> fclose(file);

Jeg prøvede nogle primitive tests på PIII med Linux. Dit forslag var
ca. 2.5 gange hurtigere ved 300.000 og ca. 3 gange hurtigere ved
3.000.000 doubles. Desuden blev programmet kortere og lettere at læse,
så alt i alt var mit forslag vist ikke så godt.

(Bemærk dog at det ovenstående kræver at du kan holde alle dine
doubles i hukommelsen på én gang, men 300.000 af dem er jo heller ikke
alverden).

Det nye program ser sådan ud:

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

static void
disaster (char *s)
{
perror (s);
exit (EXIT_FAILURE);
}

enum {
N_DOUBLES = 3000000
};

static double darray1[N_DOUBLES];
static double darray2[N_DOUBLES];

int
main ()
{
int i;
FILE *f;

for (i = 0; i < N_DOUBLES; i++)
   darray1[i] = 2000 * drand48 ();

f = fopen ("testfil", "wb");
if (f == NULL)
   disaster ("fopen");
if (fwrite (darray1, sizeof(double), N_DOUBLES, f) != N_DOUBLES)
   disaster ("fwrite");
fclose (f);

f = fopen ("testfil", "rb");
if (f == NULL)
   disaster ("fopen");
if (fread (darray2, sizeof (double), N_DOUBLES, f) != N_DOUBLES)
   disaster ("fread");
fclose (f);

for (i = 0; i < N_DOUBLES; i++)
   if (darray1[i] != darray2[i])
    {
      fprintf (stderr, "darray1[%d] != darray2[%d] (%f, %f)\n",
          i, i, darray1[i], darray2[i]);
      exit (EXIT_FAILURE);
    }
return EXIT_SUCCESS;
}


Byrial Jensen (06-03-2001)
Kommentar
Fra : Byrial Jensen


Dato : 06-03-01 23:12

Soeren Sandmann <sandmann@daimi.au.dk> skrev:
>
>Normalt kan man roligt regne med at standardimplementationerne af
>filadgangsfunktionerne er bedre end hvad man selv kan lave med read(),
>write() mv.. Standardfunktionernes har normalt buffere som er
>tilpasset systemet bedre end man selv kan gøre (i hvert fald bedre end
>man selv kan gøre portabelt).

Enig. Men hvis man vil give afkald på portabilitet, kan man med
stat(2) på nogle unix'er få en anbefalet bufferstørrelse til
effektiv I/O til en fil.

> if (fwrite (darray1, sizeof(double), N_DOUBLES, f) != N_DOUBLES)
>   disaster ("fwrite");
> fclose (f);

Tjek altid for fejl ved lukning af filer som der er skrevet til!
Der kan og må nemlig godt være data gemt i interne buffere som
først forsøges skrevet ved lukningen.

> if (fread (darray2, sizeof (double), N_DOUBLES, f) != N_DOUBLES)
>   disaster ("fread");
> fclose (f);

Her betyder det manglende tjek mindre.

Per Abrahamsen (03-03-2001)
Kommentar
Fra : Per Abrahamsen


Dato : 03-03-01 12:28

Kaare Brandt Petersen <kaare@netcetera.dk> writes:

> fopen("foo","wb");
>
> skulle gerne returnere en filestruct saa man kan skrive binaert til filen
> 'foo'.

"binært" i denne sammenhæng betyder at linieskift *ikke* konverteres
mellem C tekstformat ("\n") og det lokale tekstformat (Unix: "\n",
Mac: "\r", DOS: "\r\n").

Som du måske kan regne ud har det ikke den store betydning under Unix.

"printf" konverterer sine argumenter til tekst. Hvis du godt vil
skrive bitrepræsentationen af C datatyper ud kan bruge "fwrite". Det
er i så fald vigtigt at du har åbnet filen binært, hvis du vil være
sikker på at eventuelle bytes 10 (C newline) ikke bliver konverteret
til 13 eller 13 10.


Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408926
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste