Avatar billede Slettet bruger
20. januar 2004 - 10:31 Der er 25 kommentarer og
1 løsning

Kan ikke skrive mere end 8.5 kb.

Hejsa,

Nogen der kan lure hvorfor jeg ikke kan generere en fil (med fwrite())på mere end ca. 8.5 kb. Det er ikke i selve scriptet begrænsningerne ligger, for det kan godt køre på en anden maskine.
Jeg kører php 4.3.4 og Apache/2.0.48 og har sat max ex3ecution time, memory limit og andre potentielle flaskehalse op.
Avatar billede Slettet bruger
20. januar 2004 - 10:40 #1
Må vi se din kode?
Avatar billede Slettet bruger
20. januar 2004 - 10:50 #2
Jeg ved godt det er imod exps ånd, men jeg vil helst ikke smide koden her, for det er ikke mig der har rettighederne til den. Men scriptet læser html koder fra en URL der gives som input. Det genererer derefter tilsvarende lokale filer, og ændrer nogle ting undervejs - bla. referencer til css, billeder osv. Men det når desværre ikke at køre færdigt og mønsteret er tilsyneladende at min opsætning ikke vil tillade scriptet at generere filer der er større end 8.5 kb. Den stopper simpelthen når den når en vis størrelse.
Avatar billede Slettet bruger
20. januar 2004 - 11:03 #3
Så bare linierne, der skriver?

Husk, at fwrite returnerer antal skrevne bytes. I andre sprog har det været påkrævet, at man undersøgte dette tal og kaldte fwrite igen med yderligere data, hvis den ikke fik skrevet det hele i første omgang.
Avatar billede amerikaner Nybegynder
20. januar 2004 - 11:06 #4
Some suggestions - not a solution...
Does fwrite() return 0 or a positive number (the number of rows it wrote)?
Are you getting a EFBIG error??
Is the stream unbuffered?
Have you specified the size and the number of items?

  t fwrite(const void *ptr, t size, t nitems, FILE *stream);

Moget at tykke på....
Avatar billede amerikaner Nybegynder
20. januar 2004 - 11:07 #5
Sku' skrive Noget (fan***n sprog)
Avatar billede Slettet bruger
20. januar 2004 - 11:09 #6
amerikaner: Du beskriver vistnok C-funktionen. Bemærk at vi snakker om PHP her. Derudover er dine betragtninger tæt på mine, så din generelle ide er god nok.
Avatar billede Slettet bruger
20. januar 2004 - 11:10 #7
### Udskriv fil
        $fp= fopen($fil['full'],'wb');
        fwrite($fp,$source);
        fclose($fp);
        }

der kommer ingen fejl og jeg ved ikke om den er buffered eller ej.
Avatar billede Slettet bruger
20. januar 2004 - 11:12 #8
sandbox > siger koden dig nogetsomhelst?
Avatar billede Slettet bruger
20. januar 2004 - 11:15 #9
Ja. Vi havde ret.

Der bliver ikke tjekket for noget som helst. Den tjekker ikke engang, om det lykkedes at åbne filen, før den prøver at skrive i den. Det er skodkode uden lige.

Jeg laver lige en bedre udgave.
Avatar billede Slettet bruger
20. januar 2004 - 11:44 #10
I den kode, du viste var en } til sidst, som ikke var en del af selve filskrivningen. Den har jeg IKKE inkluderet i min kode. Jeg har ikke afprøvet koden, men den burde virke.

// Udskriv fil
if($fp= fopen($fil['full'],'wb')){
  $tmpsource=$source;
  while(strlen($tmpsource)>0){
    $written=fwrite($fp,$tmpsource,strlen($tmpsource));
    if($written===FALSE){
      $tmpsource='';
      echo "Fejl under skrivning til fil!";
    } else {
      $tmpsource=substr($tmpsource,$written);
    }
  }
  fclose($fp);
} else {
  echo "Kunne ikke åbne fil for skrivning!"
}
Avatar billede Slettet bruger
20. januar 2004 - 11:47 #11
Hvis $source ikke skal bruges igen efter skrivningen, kan du droppe linien $tmpsource=$source; og rette $tmpsource til $source over det hele. Jeg brugte bare en ekstra variabel for ikke at ødelægge indholdet af din allerede eksisterende variabel.
Avatar billede Slettet bruger
20. januar 2004 - 11:53 #12
sandbox > Det er muligt at det blev bedre kode af det, men det hjalp nu ikke på problemet :(
Avatar billede erikjacobsen Ekspert
20. januar 2004 - 12:15 #13
Jeg ikke problemet er skrivningen, men indholdt af $source, der i det tilfælde
vi snakker om her, ganske enkelt kun indeholder 8.5 kB - men det er lidt (*g*)
svært at sige hvad der er galt uden koden.
Avatar billede Slettet bruger
20. januar 2004 - 12:15 #14
Kan det være, at den ikke modtager hele filen?

Prøv at indsætte følgende linie:

// Udskriv fil
echo "Har " . strlen($source) . " bytes til skrivning.";
if($fp= fopen($fil['full'],'wb')){
Avatar billede Slettet bruger
20. januar 2004 - 12:22 #15
sandbox >

Har 8745 bytes til skrivning.
Har 8703 bytes til skrivning.
Har 8702 bytes til skrivning.
Har 8702 bytes til skrivning.
Har 8702 bytes til skrivning.
Har 8702 bytes til skrivning.
Har 8702 bytes til skrivning.
Har 8702 bytes til skrivning.
Har 5719 bytes til skrivning.
Har 5394 bytes til skrivning.

hvor f.eks. den første burde være 9739 bytes...
Avatar billede Slettet bruger
20. januar 2004 - 12:46 #16
Tjah, så er det ikke filskrivningen den er gal med.
Avatar billede Slettet bruger
20. januar 2004 - 12:47 #17
noget tyder vel på at det min lokale opsætning den er gal med, for scriptet kører fint på en anden maskine :(
Avatar billede Slettet bruger
20. januar 2004 - 12:50 #18
Eller også er der bare skodkode andre steder, som ikke laver tingene korrekt. Måske en regex, der fjerner for meget eller hvad ved jeg.

Prøv at få scriptet til at udskrive filstørrelsen lige efter den er indlæst og sammenlign med hvis du havde hentet filen manuelt.
Avatar billede Slettet bruger
20. januar 2004 - 12:56 #19
Prøv at få scriptet til at udskrive filstørrelsen lige efter den er indlæst og sammenlign med hvis du havde hentet filen manuelt.

Er det ikke det jeg gør 20/01-2004 12:22:19 ?
Avatar billede Slettet bruger
20. januar 2004 - 13:07 #20
Nej det går jeg da ikke ud fra.

Du siger, at scriptet gør disse ting:

1: henter en fil.
2: henter underfiler og gemme lokalt.
3: retter i filen fra #1, så referencer til filerne fra #2 passer med de lokale udgaver.
4: gemmer den rettede fil.

Det er vel efter at scriptet har lavet sine rettelser i filen, og skal til at gemme den, at du udskrev størrelsen. Det var ihvertfald der, jeg bad dig udskrive størrelsen.
Avatar billede Slettet bruger
21. januar 2004 - 08:52 #21
OK, en fil som ved manuel hentning fylder 13915 bytes, fylder lige efter indlæsning, 8581 bytes.
Avatar billede Slettet bruger
21. januar 2004 - 08:56 #22
Og koden som indlæser er som følger

        $fp= fopen($url['full'],'r');
        $source= fread ($fp, 64000);
        fclose($fp);
Avatar billede Slettet bruger
21. januar 2004 - 09:43 #23
Så er det klart - PHP-manualen siger:

When reading from network streams or pipes, such as those returned when reading remote files or from popen() and proc_open(), reading will stop after a packet is available. This means that you should collect the data together in chunks as shown in the example below.

Oversat får du altså data lige så snart den første pakke er parat.

Jeg tager lige deres eksempel og tilretter til din kode.

$fp = fopen($url['full'], "rb");
$source = '';
do {
  $data = fread($fp, 8192);
  if (strlen($data) == 0) {
      break;
  }
  $source .= $data;
} while (true);
fclose($fp);
Avatar billede Slettet bruger
21. januar 2004 - 09:44 #24
Og nu nærmer vi os vist det punkt, hvor det skal være et svar.
Avatar billede Slettet bruger
21. januar 2004 - 10:04 #25
fantastisk :) tusind tak for hjælpen !!
Avatar billede Slettet bruger
21. januar 2004 - 13:59 #26
OK, så vil jeg gå ud fra, at det virker nu. ;-)
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
Vi tilbyder markedets bedste kurser inden for webudvikling

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