Linux atomarer Dateizugriff

Gast #3773596
Lesenswert?

Hallo,

Ich möchte mit einem Raspberry Pi und einer USB-Webcam regelmäßig ein 
Foto machen (Cronjob). Dieses wird in einem Verzeichnis gespeichert, 
welches über den Webserver zugänglich ist, der ebenfalls auf dem Pi 
läuft. Nun soll eine Internetseite das jeweils aktuelle jpg-Foto 
einbinden (immer der gleiche, statische Dateiname). Das Problem ist nun, 
dass ich nicht weiß, wie ich verhindere, dass man das Foto über den 
Webserver holt während die das Skript gerade ein neues Foto in das 
Verzeichnis schreibt. Das heißt ich möchte, dass das neue Foto erst ab 
dem Zeitpunkt zugreifbar ist, wenn es vollständig gespeichert ist. Wie 
kann ich das machen? Gibt es da eine Art Mutex, die den Webserver ein 
paar Millisekunden hinhalten kann, wenn gerade noch gespeichert wird? 
Oer wie würdet ihr das Problem lösen?

Ich weiß, dass dieses Forum thematisch nicht 100%ig auf die Thematik 
meiner Frage ausgelegt ist. Ich habe hier aber schon oft kompetente 
Foristen mit pragmatischen Lösungsansätzen gelesen und hoffe daher, dass 
mir hier jemand helfen kann.

Vielen Dank schon mal im Voraus!

Freiherr Isidor von Dornheim-Rottenburg
Gast #3773613
Lesenswert?

Oh, dafür liebe ich dieses Forum! funktioniert das auch, wenn am Zielort 
zuvor eine Datei mit gleichem Namen ist, die ersetzt wird? Weil die 
Internetseite ja immer auf den gleichen Dateinamen zugreift.
Danke!
#3773617
Lesenswert?

Gustav schrieb:
> move

Das Kommando heisst "mv", als Betriebssystemaufruf heisst das rename() !
Natuerlich muss man die alte Datei vor dem rename() loeschen mit 
"unlink()", oder ? Und dann ist es leider nicht mehr atomar. Wird aber 
wahrscheinlich trotzdem klappen.

Update: Ups, nicht vorher loeschen, denn rename() macht das schon wenn 
die Zeildatei existiert ! Haette vorher mal die manpage anschauen sollen 
...

Es gibt sogar eine weitreichende Garantie:

The rename() system call guarantees that an instance of new will always
     exist, even if the system should crash in the middle of the 
operation.

Nett, oder ?
Gast #3773649
Lesenswert?

Kai S. schrieb:
> The rename() system call guarantees that an instance of new will always
>      exist, even if the system should crash in the middle of the
> operation.
>
> Nett, oder ?

nein, denn es garantiert nur das die Datei immer Vorhanden ist. Entweder 
über den neuen oder den alten Namen.

Es garantiert nicht, das die Zieldatei immer verfügbar ist. Das das 
Problem bekannt ist, wurde im einer der letzter Kernel Version eine 
neuer Syscall eingebaut, der 2 Dateien atomar tauscht.

@Freiherr Isidor von Dornheim
Es sind nicht sehr sinnvoll ständig auf der Festplatte rumzuschreiben, 
dafür sie die SD-Karten nicht gedacht.

Ich würde das Image einfach im Ram speichern, für Webserver bietet sich 
z.b. memcache an.
Gast #3773695
Lesenswert?

Und wie schreibe ich eine Datei in den Ram? Ist memcache ein Mountpoint, 
über den das RAM im Dateisystem zugängig ist? Eigentlich wollte ich alle 
Bilder auch archivieren. Dafür müsste ich ohnehin auf die SD-Karte (oder 
ein USB-Medium) schreiben.
Gast #3773699
Lesenswert?

Freiherr Isidor von Dornheim-Rottenburg schrieb:
> Und wie schreibe ich eine Datei in den Ram? Ist memcache ein Mountpoint,
> über den das RAM im Dateisystem zugängig ist? Eigentlich wollte ich alle
> Bilder auch archivieren. Dafür müsste ich ohnehin auf die SD-Karte (oder
> ein USB-Medium) schreiben.

memcache ist keine Ramdisk sondern ein Programm.

http://de.wikipedia.org/wiki/Memcached

> Eigentlich wollte ich alle
> Bilder auch archivieren. Dafür müsste ich ohnehin auf die SD-Karte (oder
> ein USB-Medium) schreiben.
davon war aber vorher keine rede.
Gast #3773730
Lesenswert?

@Peter II: Ok, aber eine Ramdisk könnte mir auch helfen um zu 
verhindern, dass die SD-Karte so schnell "abgenutzt" wird. Dort könnte 
ich immer das aktuelle Foto ablegen. Zum Archivieren könnte ich auf ein 
externes Laufwerk (usb-Festplatte) ausweichen.
Dass ich das mit dem Archivieren zuerst nicht geschrieben habe, war weil 
ich nicht dachte, dass das relevant für mein Problem wäre, Sorry

Gruß
Freiherr Isidor von Dornheim-Rottenburg
Gast #3773734
Lesenswert?

Ihr Vollpfosten solltet mal nachlesen was "atomar" bedeutet.
Bei Speichermedien mit FS ist gar kein Zugriff atomar.

Man kann höchstens die Zeitspanne verkürzen, in der die
Bilddatei geschrieben wird, in der Hoffnung, dass es
dann seltener vorkommt, dass der Webserver während
der Speicherung das Bild lädt und darstellt.
Scheinbar ist das Programm, welches das Bild macht und
abspeichert, langsamer als move.
Gast #3773752
Lesenswert?

wenn du alle Bilder aufheben willst, kannst du sie unter einem 
eindeutigen Namen (2014-08-22-1050 oder so) auf die SD-Karte schreiben 
und dann die gerade geschriebene Datei nach /tmp kopieren. Anschließend 
wird sie mit mv umbenannt, damit der Name für den Webserver immer gleich 
bleibt.

Auf die Art wird genau so viel wie nötig und so wenig wie möglich auf 
die SD-Karte geschrieben. Für /tmp verwendet man heutzutage "tmpfs"; 
normal sollte das sowieso so eingerichtet sein.
Gast #3773764
Lesenswert?

Peter II schrieb:
> Gustav schrieb:
>> Peter II schrieb:
>>> und schon haben wir wieder das atomar Problem.
>>
>> Nein.
>
> doch. Die Datei wird kurzzeitig nicht verfügbar sein.

Nein.
1
Foto.jpeg ---> altes_bild
2

3
Foto.jpeg ---> altes_bild
4
201408221050 ---> halbes_neues_bild
5

6
Foto.jpeg ---> altes_bild
7
201408221050 ---> neues_bild
8

9
mv 201408221050 Foto.jpeg
10

11
Foto.jpeg ---> neues_bild
oder wie sonst läuft das ab?
Gast #3773772
Lesenswert?

Schaulus Tiger schrieb:
> mv 201408221050 Foto.jpeg

das ist das Problem.

Wenn im Hintergrund ein Programm ständig auf Foto.jpeg zugreifst, wirst 
du merken das es kurzeitig nicht das ist.

Du bekommst du Datei für einen kurzen Moment nicht geöffnet, weil sie 
nicht da ist.

Für eine Webcam mag das ok sein, sauber ist es so auf jeden fall nicht.
Gast #3773775
Lesenswert?

so hier noch das Problem:

http://www.heise.de/open/artikel/Kernel-Log-Was-3-15-bringt-1-Dateisysteme-und-Storage-2183256.html

Atomar umbenennen

Über den neuen Syscall "renameat2()" kann Software den Kernel anweisen, 
zwei Dateien atomar auszutauschen. Userspace-Programme sehen so entweder 
den alten oder neuen Zustand, nie aber einen der Zustände im 
Umbenennungsprozess. Das ist unter anderem zur sauberen Implementierung 
von Dateisystemen wichtig, die per "Union Mounting" mehrere Dateisysteme 
zu einem verbinden; das nutzen beispielsweise Live-Linuxe, um den Inhalt 
einer schreibgeschützten DVD mit dem Inhalt eines beschreibbaren 
USB-Sticks zu einem einzelnen Dateisystem zu verknüpfen, das alle neu 
geschriebenen Daten auf dem USB-Stick ablegt. Der neue Syscall ist damit 
ein wichtiger Schritt zur Union-Mount-Unterstützung im Kernel, auf die 
wechselnde Entwickler seit über fünfzehn Jahren hinarbeiten.
#3773788
Lesenswert?

Freiherr Isidor von Dornheim-Rottenburg schrieb:
> Und wie schreibe ich eine Datei in den Ram? Ist memcache ein Mountpoint,
> über den das RAM im Dateisystem zugängig ist?

Wenn du nichtsa auf der SDCard speichern willst, bietet sich auch ein 
tmpfs an.
Auf einem Olimex A20 mit Debian sieht es z.B. so aus:
<pre>
klaus@A20:~ > df
Filesystem     1K-blocks     Used Available Use% Mounted on
rootfs          30667212 19767816   9341952  68% /
/dev/root       30667212 19767816   9341952  68% /
devtmpfs          415368        0    415368   0% /dev
tmpfs              83096      180     82916   1% /run
tmpfs               5120        0      5120   0% /run/lock
tmpfs             166180       92    166088   1% /run/shm
</pre>
In die run/-Verzeichnisse kann man munter schreiben, owohl die effektiv 
nur im RAM sind.
Weitere könnte man sich schaffen...


> Eigentlich wollte ich alle
> Bilder auch archivieren. Dafür müsste ich ohnehin auf die SD-Karte (oder
> ein USB-Medium) schreiben.

Dann brauchst du auch kein RAM zum Speichern.

Idee: mit fortlaufenden Namen auf der SDCard speichern, und anschließend 
jeweils einen symbolischen Link mit festem Namen auf die letzte Datei 
richten.
Über den Link greift dann dein Webserver zu.
Damit das wiederum nicht kollidiert, könnte man jeweils den neuen Link 
mit einem temprären Namen anlegen (z.B. in einem tmpfs-Verzeichnis) und 
anschließend in den richtigen Namen umbenennen.
So hats du alles, was archiviert bleiben soll, auf der Karte und alles 
dynamische im RAM.
Gast #3773794
Lesenswert?

Klaus Wachtler schrieb:
> Damit das wiederum nicht kollidiert, könnte man jeweils den neuen Link
> mit einem temprären Namen anlegen (z.B. in einem tmpfs-Verzeichnis) und
> anschließend in den richtigen Namen umbenennen.

und das ist schon wieder nicht Atomar. Beim umbenennen gibt es 
kurzzeitig da Ziel nicht mehr.
Gast #3773796
Lesenswert?

>Es sind nicht sehr sinnvoll ständig auf der Festplatte rumzuschreiben,
>dafür sie die SD-Karten nicht gedacht.

Cronjobs habe normalerweise in minimale Auflösung von 1 Minute.
Das wird für die SD-Karten wohl nicht so kritisch sein??!
Das System schreibt sowieso viel auf der SD-Platte "rum".
Gast #3773801
Lesenswert?

Thorsten schrieb:
> Ein mv(1) auf dem selben Dateisystem bzw. rename(2) ist unter Linux und
> jedem anständigen Unix atomar und garantiert auch, dass die Datei zu
> jedem Zeitpunkt mit open(2) geöffnet werden kann.

wo steht das genau?

wenn ich Datei X nach Y umbenenne, dann heist das das X immer lesbar 
ist, zu Y erfolgt keine Aussage.

Wir haben zumindest und Linux das Problem gehabt, das beim umbenennen 
genau zu diesen Problem kommt.
Gast #3773803
Lesenswert?

Nürnberger schrieb:
> Cronjobs habe normalerweise in minimale Auflösung von 1 Minute.
> Das wird für die SD-Karten wohl nicht so kritisch sein??!
> Das System schreibt sowieso viel auf der SD-Platte "rum".

warum sollte es da tun? Festplatten schaltet sich sogar bei einem 
timeout von 10min ab, weil nichts zu schreiben ist.
Gast #3773823
Lesenswert?

Gustav schrieb:
> Das kannst du noch so oft behaupten, es wird dadurch aber nicht richtig.

ok geben micht geschlagen:

http://man7.org/linux/man-pages/man2/rename.2.html
 If newpath already exists, it will be atomically replaced (subject to
       a few conditions; see ERRORS below), so that there is no point at
       which another process attempting to access newpath will find it
       missing.

aber wir hatte zumindest Probleme damit, er verlasse mich nicht darauf.
Gast #3773828
Lesenswert?

Peter II schrieb:
> wenn ich Datei X nach Y umbenenne, dann heist das das X immer lesbar
> ist, zu Y erfolgt keine Aussage.

Bei einem
  rename("old", "new");
bei existentem "new" ist garantiert dass "new" während des Umbennenens 
immer existiert und gelesen werden kann. Ohne diese Semantik würden 
etliche Programme nicht korrekt funktionieren.

Nachlesen kann man das unter anderem in POSIX 1998. Zitat:

If the link named by the new argument exists, it shall be removed and 
old renamed to new. In this case, a link named new shall remain visible 
to other processes throughout the renaming operation and refer either to 
the file referred to by new or old before the operation began.
Gast #3773835
Lesenswert?

Peter II schrieb:
> Nürnberger schrieb:
>> Cronjobs habe normalerweise in minimale Auflösung von 1 Minute.
>> Das wird für die SD-Karten wohl nicht so kritisch sein??!
>> Das System schreibt sowieso viel auf der SD-Platte "rum".
>
> warum sollte es da tun? Festplatten schaltet sich sogar bei einem
> timeout von 10min ab, weil nichts zu schreiben ist.

Naja, ein aktiver webserver loggt ja alles mögliche.
(ok, das könnte man sicherlich deaktivieren)
Üblicherweise wird für log-Daten kein tmp-Verzeichnis gewählt,
denn dann wären diesen Daten nach einem System-Absturz weg.
Gast #3773836
Lesenswert?

bevor du eine neue datei schreibst löschst du die alte (mit dem selben 
namen). falls die alte grade geöffnet war kann das programm immernoch 
den inhalt lesen (und reinschreiben). eine alte unix hacktechnik um 
unsichtbar daten wegschreiben zu können - die datei taucht als name im 
FS nicht auf, aber das handle ist noch geöffnet und es kann ganz normal 
darauf zugegriffen werden.

für den fall das deine websoftware genau dann ein bild laden will wenn 
die alte datei eben gelöscht, aber nie neue noch nicht angelegt wurde, 
machst du zwei zugriffe mit einem timeout(<erstellungsintervall) 
dazwischen.


es gibt übrigens noch die möglichkeit video direkt zu streamen (weiß 
aber nicht ob der raspi das eventuelle transcoden schafft) - falls du es 
ganz hardcore haben willst ;)
(Firma: Brainit GmbH) #3773844
Lesenswert?

Peter II schrieb:
> und warum wird dann extra eine neue Kernel Funktion geschrieben?

Ihr verwechselts da was:

rename() ist per Definition atomar

was nciht atomar ist, ist das Vertauschen zweier Dateien,

also a.txt  und b.txt austauschen
weil das nur als drei einzelne rename() calls abgebildet werden kann
rename a.txt x.txt
rename b.txt a.txt
rename x.txt b.txt

jeder der einzelnen rename() ist zwar für sich atomar, aber nicht die 
drei operationen zusammen.

Deshalb (und nur deshalb) gibts den neuen SysCall (der auch nur für 
einen speziellen Zweck eingebaut wurde, nämlich union-filesystems)
Gast #3773849
Lesenswert?

Freiherr Isidor von Dornheim-Rottenburg schrieb:
> @Peter II: Ok, aber eine Ramdisk könnte mir auch helfen um zu
> verhindern, dass die SD-Karte so schnell "abgenutzt" wird.

Vergiss das mit der schnellen Abnutzung.

Ich habe hier einen 32GB USB Stick (Sandisk Cruzer Blade), auf den 
werden täglich (24/7/365) 12960 jpgs von 5 Kameras geschrieben, ca. 
50..100kB pro jpg je nach cam.

Zusätzlich noch 1x täglich je ein Zeitraffervideo von 50...175MB pro 
cam.

Auslastung des Sticks schwankt zwischen 50%...80%, d.h. ich habe immer 
mindestens 20% des Speicherplatzes frei.

Der Stick ist seit mehr als einem Jahr im Einsatz, ohne 
Ausfallerscheinungen.

Wenn USB Sticks kaputtgehen, dann nicht durch "Abnutzung" durch häufiges 
Schreiben, sondern durch mechanische Belastung.
Gast #3773862
Lesenswert?

Schaulus Tiger schrieb:
> Foto.jpeg ---> altes_bild
>
> Foto.jpeg ---> altes_bild
> 201408221050 ---> halbes_neues_bild
>
> Foto.jpeg ---> altes_bild
> 201408221050 ---> neues_bild
>
> mv 201408221050 Foto.jpeg
>
> Foto.jpeg ---> neues_bild

Exakt so mache ich das auch (anderer Rechner als der vorhin beschriebene 
mit 5 cams) und konnte bisher keine "kurzfristige" Nicht-Verfügbarkeit 
feststellen.

Für den angedachten Anwendungszweck funktioniert das hervorragend.

Und btw: Kann bitte mal jemand das schon so oft genannte "kurzfristig" 
näher quantifizieren? Ich behaupte, das "kurzfristig" ist so kurz, daß 
es keine praktische Relevanz hat.
Gast #3773931
Lesenswert?

Peter II schrieb:
> tmomas schrieb:
>> Vergiss das mit der schnellen Abnutzung.
>
> ich habe schon 2 stick mit 2GB damit geschrotet. Hatte ein normales
> Linux drauf und /var nicht auf ein tmpfs gelegt.
>
> Nach jeweils 1Jahr hatte der Stick Schreibfehler.

Welche Marke?
Wieviele Dateien bzw. MB/Tag hast du draufgeschrieben?


- Nimm einen Markenstick (Sandisk Cruzer Blade / Sandisk Cruzer fit sind 
meine Lieblinge)
- Nimm einen "großen" Stick. 8 oder 16GB kosten ja heute nichts mehr.
- Sorge dafür, daß immer ca. 20% frei sind. Betonung auf immer.
- Die jpgs und videos werden bei mir regelmäßig gelöscht, d.h. alle 
Speicherzellen werden mehr oder weniger gleichmäßig belastet. Es gibt 
nicht die Situation, daß von den 32GB 30GB dauerhaft belegt sind, und 
nur auf den restlichen 2GB rumgeschrieben wird.

Anmerkung: /var liegt bei mir auf einem tmpfs.
Gast #3774792
Lesenswert?

tmomas schrieb:
> Und btw: Kann bitte mal jemand das schon so oft genannte "kurzfristig"
> näher quantifizieren? Ich behaupte, das "kurzfristig" ist so kurz, daß
> es keine praktische Relevanz hat.

Null, jedenfalls in diesem Anwendungsfall mit "mv"; ich glaube, soweit 
waren wir uns inzwischen einig.

Man kann natürlich gemein sein: Das "mv" braucht eine gewisse 
Ausführungszeit, gerade auf SD-Karten (im Extremfall wohl über 1 
Sekunde). Und gerade weil es atomar ist, ist während der Zeit kein 
Zugriff möglich. Es gibt zwar keinen Fehler oder falsche Daten, aber 
wenn diese Verzögerung stört...
#3775191
Lesenswert?

Freiherr Isidor von Dornheim-Rottenburg schrieb:
> Das Problem ist nun,
> dass ich nicht weiß, wie ich verhindere, dass man das Foto über den
> Webserver holt während die das Skript gerade ein neues Foto in das
> Verzeichnis schreibt. Das heißt ich möchte, dass das neue Foto erst ab
> dem Zeitpunkt zugreifbar ist, wenn es vollständig gespeichert ist. Wie
> kann ich das machen?

schreib doch das neue Foto mit einem eindeutigen Namen in ein 
Verzeichnis (damit hast du gleichzeitig auch noch ein Archiv) und setz 
nach dem speichern einfach einen symlink (z.b. current) auf das 
aktuellste Bild.
Einen Symlink zu erstellen/ändern sollte (theoretisch) schneller sein 
als das Bild zu speichern
#3777533
Lesenswert?

Ein ganz wichtiger Fakt zu unlink() und rename() wurde hier noch nicht 
erwähnt:

Wenn ein Prozess die Datei zu dem Zeitpunkt offen hatte zu dem unlink() 
oder rename() passierte bekommt besagter Prozess gar nichts davon mit, 
Änderungen werden in die umbenannte oder scheinbar gelöschte Datei 
geschrieben (die erst wirklich bei Prozessende gelöscht wird!).
Wer es nicht glaubt öffne mal eine MP3-Datei in irgendeinem Player auf 
einem Linux/Unix-System und verschiebe oder lösche sie während sie 
abgespielt wird...
Gast #3777662
Lesenswert?

Guten Morgen,
danke für eure Hilfe in dieser Sache. Hier kamen wirklich von allen 
Seiten sehr konstruktive Beiträge!

 @Andy D. : Ja, das finde ich ziemlich gut. Mir ist es wichtig, dass zu 
JEDER Zeit ein vollständiges, nicht korrumpiertes Foto zur Verfügung 
steht. Auch wenn gerade ein neues aufgenommen/abgespeichert wird.

@all:
Der Raspberry-Webcamserver soll über eine Dyn-DNS im Netz hängen. Ich 
möchte aber nicht, dass jeder Besucher meiner Seite gleich "zu mir nach 
Hause gehen kann" - ich möchte die Dyndns nicht im für Seitenbesucher 
sichtbaren Seitenquelltext stehen haben. Gibt es eine Möglichkeit, den 
Hauptwebserver mit php dazu zu bringen (regelmäßig) das neueste Foto vom 
Webcamwebserver zu holen und dann aus einem eigenen Verzeichnis zum 
Seitenbesucher zu bringen?

Ich hoffe ich konnte verständlich machen, was ich möchte. Wenn nicht, 
einfach nochmal nachhaken ;)

Vielen Dank schon mal im Voraus!

Freiherr Isidor von Dornheim-Rottenburg
#3777695
Lesenswert?

Freiherr Isidor von Dornheim-Rottenburg schrieb:
> Gibt es eine Möglichkeit, den
> Hauptwebserver mit php dazu zu bringen (regelmäßig) das neueste Foto vom
> Webcamwebserver zu holen und dann aus einem eigenen Verzeichnis zum
> Seitenbesucher zu bringen?

z.B. curl
in verbindung mit einem blow- äh cronjob (regelmäßig) oder auch direkt 
bei einem seitenaufruf (on demand). welche variante die geschicktere ist 
hängt u.a. auch von der anzahl der seitenaufrufe ab.
dabei kannst du das foto auch noch gleich mit einem wasserzeichen 
versehen, verkleinern, drehen, was auch immer
1
function getImg() {
2
  $ch = curl_init('http://dein.raspberry.com/webcam/current.jpg');
3

4
  curl_setopt_array($ch, array(
5
    CURLOPT_RETURNTRANSFER => true,
6
  ));
7

8
  $img = curl_exec($ch);
9
  curl_close($ch);
10

11
  $fh = fopen('current.jpg', 'x+');
12
  fwrite($fh, $img);
13
  fclose($fh);
14

15
  echo '<img src="current.jpg" alt="xxx">';
16
}

bitte auf evtl. funktionsnamen, optionen, parameter, etc. nicht 100% 
festnageln - habs nur aus dem kopf geschrieben und nicht nachgeschaut. 
der code soll ja auch mehr das prinzip verdeutlichen
Gast #3777746
Lesenswert?

OK danke,
ich denke ich werde es wohl bei Seitenaufruf machen müssen, weil ich bei 
dem Hauptwebserver nur ftp-Zugriff und einen (eingeschränkten) 
Datenbank-Zugang habe. Ich kann also keinen Cron-Job installieren. Oder 
kann man das auch auf eine andere Art und Weise regelmäßig laufen 
lassen? Ich habe mit php leider noch keine Erfahrungen gemacht.
Gast #3778577
Lesenswert?

Freiherr Isidor von Dornheim-Rottenburg schrieb:
> Gibt es eine Möglichkeit, den
> Hauptwebserver mit php dazu zu bringen (regelmäßig) das neueste Foto vom
> Webcamwebserver zu holen und dann aus einem eigenen Verzeichnis zum
> Seitenbesucher zu bringen?

Wie schon erwähnt: cronjob + curl oder auch ein einfaches wget

Alternativ: Laß doch den Raspi das neue Bild auf den Hauptserver 
hochladen. Auf dem hast du doch alle Möglichkeiten, oder zumindest mehr 
Möglichkeiten, als auf dem Hauptserver, oder?
Gast #3778981
Lesenswert?

Ja, auf dem Raspberry habe ich freie Hand. Ich kann also das Foto von da 
aus per ftp zum Webserver befördern. Dann stellt sich aber erneut die 
Frage, ob ich das jeweils aktuelle Foto zum Webserver laden kann (und 
dabei das vorherige überschreiben) und dabei zu JEDER Zeit ein nicht 
korrumpiertes Foto an den Website-Besucher ausliefern kann?
#3779556
Lesenswert?

Freiherr Isidor von Dornheim-Rottenburg schrieb:
> zu JEDER Zeit ein nicht
> korrumpiertes Foto an den Website-Besucher ausliefern kann?

Machs mit zwei Dateien und drei Dateinamen:

RPi macht über FTP:
Upload TMPFILE
Delete IMAGE1.JPG
Rename TMPFILE IMAGE1.JPG
Upload TMPFILE
Delete IMAGE2.JPG
Rename TMPFILE IMAGE2.JPG
Goto 10;

Dein PHP macht:

IMAGE1handle = fopen IMAGE1.JPG
IMAGE2handle = fopen IMAGE2.JPG

fstat IMAGE1handle (wenn OK)
fstat IMAGE2handle (wenn OK)

neueres Auswählen (wenn beide OK)
ggfs: fclose auf unbenötigten (älteren) Handle

Bild rausstreamen. (while... fread ... )

fclose

Trick ist: kein file_exists-Check o.Ä. vorher machen, direkt fopen 
verwenden, Rückgabewert auswerten.
Das Filehandle bleibt gültig, auch wenn gleichzeitig der FTP-Server ein 
"unlink" ausführt.

Dein Problem verschiebt sich damit vom Atomaren Umbennenen zum Atomaren 
Löschen von Dateien. Und das ist m.W.n. gegeben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren