Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Bezpieczny zapis i odczyt, Niebanalna sprawa.
xpose
post
Post #1





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 29.11.2004

Ostrzeżenie: (0%)
-----


Witam wszystkich.
Napewno wielu z Was slyszalo o niezawodnosci funkcji flock(), tak samo jak i ja.
Niestety w praktyce sprawa wyglada zupelnie inaczej. Przy dosc duzym obciazeniu - rzedu 200 uzytkownikow na sekunde - funkcja ta poprostu odpusza a efektem tego jest usuwanie zawartosci blokowanych plikow lub ich czesciowa destrukcja. Oto kod ktory wywoluje ta sytuacje:

  1. <?
  2. // =========================
  3. // OPERACJE NA PLIKACH
  4. // -------------------------
  5.  
  6. function file_DeleteLine ($filename, $index) {
  7. $file = file ($filename);
  8.  
  9. $fp = fopen ($filename, "w");
  10. flock($fp, LOCK_EX);
  11. for( $w = 0; $w < count($file); $w++ )
  12. {
  13. if ($index <> $w)
  14. fwrite ($fp, $file[$w]);
  15. }
  16. flock($fp, LOCK_UN);
  17. fclose($fp);
  18. }
  19.  
  20. function file_UpdateLine ($filename, $index, $line) {
  21. $file = file ($filename);
  22. $file[$index] = $line . "rn";
  23.  
  24. $fp = fopen ($filename, "w");
  25. flock($fp, LOCK_EX);
  26. for( $w = 0; $w < count($file); $w++ )
  27. {
  28. fwrite ($fp, $file[$w]);
  29. }
  30. flock($fp, LOCK_UN);
  31. fclose($fp);
  32. }
  33.  
  34. function file_GetLine ($filename, $index) {
  35. $file = fopen ($filename, "r");
  36. $line = -1;
  37. while (!feof ($file)) {
  38. $buffer = fgets($file, 4096);
  39. $line++;
  40. if ($line == $index) {
  41. fclose ($file);
  42. return $buffer;
  43. }
  44. }
  45. fclose ($file);
  46. }
  47.  
  48. function file_LinesCount ($filename) {
  49. if (file_exists($filename)) {
  50. if (filesize($filename) < 500000) {
  51. $file = file($filename);
  52. return count($file);
  53. } else {
  54. $file = fopen($filename, 'r');
  55. while (!feof ($file)) {
  56. fgets($file, 4096);
  57. $lines++;
  58. }
  59. fclose ($file);
  60. return $lines - 1;
  61. }
  62. } else return 0;
  63. }
  64.  
  65. function file_ReplaceLines ($filename, $from, $to) {
  66. $file = file ($filename);
  67.  
  68. $line = $file[$from];
  69. $file[$from] = $file[$to];
  70. $file[$to] = $line;
  71.  
  72. $fp = fopen ($filename, "w");
  73. flock($fp, LOCK_EX);
  74. for( $w = 0; $w < count($file); $w++ )
  75. {
  76. fwrite ($fp, $file[$w]);
  77. }
  78. flock($fp, LOCK_UN);
  79. fclose($fp);
  80. }
  81.  
  82. function file_InsertLine ($filename, $line) {
  83. $fp = fopen ($filename, "a");
  84. flock($fp, LOCK_EX);
  85. fputs ($fp, $line . "rn");
  86. flock($fp, LOCK_UN);
  87. fclose ($fp);
  88. }
  89.  
  90. function file_InsertLineOnTop ($filename, $line) {
  91. if (file_exists($filename)) {
  92. $fp = fopen ($filename, "r");
  93. if (filesize($filename) > 0) {
  94. $old_file = fread($fp, filesize($filename));
  95. }
  96. fclose ($fp);
  97. }
  98.  
  99. $fp = fopen ($filename, "w");
  100. flock ($fp, LOCK_EX);
  101. $file = $line . "rn" . $old_file;
  102. $file = str_replace ("rnrn", "rn", $file);
  103. fputs ($fp, $file);
  104. flock ($fp, LOCK_UN);
  105. fclose ($fp);
  106. }
  107.  
  108. function file_MoveLineToTop ($filename, $index) {
  109. $line = file_GetLine($filename, $index);
  110. file_DeleteLine($filename, $index);
  111. file_InsertLineOnTop($filename, $line);
  112. }
  113.  
  114. function file_SaveToFile ($filename, $something) {
  115. $fp = fopen ($filename, "w");
  116. flock($fp, LOCK_EX);
  117. fputs ($fp, $something);
  118. flock($fp, LOCK_UN);
  119. fclose ($fp);
  120. }
  121.  
  122. function file_ReadFromFile ($filename) {
  123. if (filesize($filename) > 0) {
  124. $fp = fopen ($filename, "r");
  125. $file = fread($fp, filesize ($filename));
  126. fclose ($fp);
  127. return $file;
  128. }
  129. }
  130.  
  131. function file_CreateFile ($filename) {
  132. $fp = fopen ($filename, "w");
  133. fclose ($fp);
  134. }
  135. ?>



W zwiazku z tym mam pytanie.
Czy jest mozliwe napisanie funkcji ktora bedzie dawala calkowita pewnosc ze dane nie zostana utracone ?

Serdecznie dziekuje za odpowiedz i pozdrawiam.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Sedziwoj
post
Post #2





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Oczywiście nie tylko do zapisu trzeba tak zrobić ale również do odczytu, aby krzaczki nie wyskakiwały (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)

Na prośbę załączam z blokowaniem, od razu mówię że nie spr. więc przejrzeć i przetestować, oraz jest kwestia file() bo przecież on również odczytuje z pliku i może się to nie powieść wtedy zwraca false.
Nie miałem doświadczenia z tak obciążonymi systemami, a manual nic nie mówi na temat blokowania pliku bo przecież go nie otwieramy... tak jak jest teraz powinno już nie być kłopotów, ale bym radził dorzucić jakiś warunek wyjścia z tych pętli, bo jak się zrobi tak że zablokuje plik do zapisu i będzie się próbowało zrobić np. file() to się po prostu zawiesi (jeśli nie zwolni tego do zapisu).

Mamnadzieje że to już będzie działać sprawnie, ale nie daję żadnej gwarancji.
  1. <?php
  2. // =========================
  3. // OPERACJE NA PLIKACH
  4. // -------------------------
  5.  
  6. function file_DeleteLine ($filename, $index) {
  7. while (($file = file($filename))==false) { usleep(100000);}
  8. $fp = fopen ($filename, "w");
  9. while (!flock($fp, LOCK_EX)) { usleep(100000);};
  10. for( $w = 0; $w < count($file); $w++ )
  11. {
  12. if ($index <> $w)
  13. fwrite ($fp, $file[$w]);
  14. }
  15. flock($fp, LOCK_UN);
  16. fclose($fp);
  17. }
  18.  
  19. function file_UpdateLine ($filename, $index, $line) {
  20. while (($file = file($filename))==false) { usleep(100000);}
  21. $file[$index] = $line . "rn";
  22. $fp = fopen ($filename, "w");
  23. while (!flock($fp, LOCK_EX)) { usleep(100000);};
  24. for( $w = 0; $w < count($file); $w++ )
  25. {
  26. fwrite ($fp, $file[$w]);
  27. }
  28. flock($fp, LOCK_UN);
  29. fclose($fp);
  30. }
  31.  
  32. function file_GetLine ($filename, $index) {
  33. $file = fopen ($filename, "r");
  34. $line = -1;
  35. while (!flock($fp, LOCK_SH)) { usleep(100000);};
  36. while (!feof ($file)) {
  37. $buffer = fgets($file, 4096);
  38. $line++;
  39. if ($line == $index) {
  40. fclose ($file);
  41. return $buffer;
  42. }
  43. }
  44. flock($fp, LOCK_UN);
  45. fclose ($file);
  46. }
  47.  
  48. function file_LinesCount ($filename) {
  49. if (file_exists($filename)) {
  50. if (filesize($filename) < 500000) {
  51. while (($file = file($filename))==false) { usleep(100000);}
  52. return count($file);
  53. } else {
  54. $file = fopen($filename, 'r');
  55. while (!flock($fp, LOCK_SH)) { usleep(100000);};
  56. while (!feof ($file)) {
  57. fgets($file, 4096);
  58. $lines++;
  59. }
  60. flock($fp, LOCK_UN);
  61. fclose ($file);
  62. return $lines - 1;
  63. }
  64. } else return 0;
  65. }
  66.  
  67. function file_ReplaceLines ($filename, $from, $to) {
  68. while (($file = file($filename))==false) { usleep(100000);}
  69. $line = $file[$from];
  70. $file[$from] = $file[$to];
  71. $file[$to] = $line;
  72. $fp = fopen ($filename, "w");
  73. while (!flock($fp, LOCK_EX)) { usleep(100000);};
  74. for( $w = 0; $w < count($file); $w++ )
  75. {
  76. fwrite ($fp, $file[$w]);
  77. }
  78. flock($fp, LOCK_UN);
  79. fclose($fp);
  80. }
  81.  
  82. function file_InsertLine ($filename, $line) {
  83. $fp = fopen ($filename, "a");
  84. while (!flock($fp, LOCK_EX)) { usleep(100000);};
  85. fputs ($fp, $line . "rn");
  86. flock($fp, LOCK_UN);
  87. fclose ($fp);
  88. }
  89.  
  90. function file_InsertLineOnTop ($filename, $line) {
  91. if (file_exists($filename)) {
  92. $fp = fopen ($filename, "r");
  93. while (!flock($fp, LOCK_SH)) { usleep(100000);};
  94. if (filesize($filename) > 0) {
  95. $old_file = fread($fp, filesize($filename));
  96. }
  97. flock($fp, LOCK_UN);
  98. fclose($fp);
  99. }
  100. $fp = fopen ($filename, "w");
  101. while (!flock($fp, LOCK_EX)) { usleep(100000);};
  102. $file = $line . "rn" . $old_file;
  103. $file = str_replace ("rnrn", "rn", $file);
  104. fputs ($fp, $file);
  105. flock ($fp, LOCK_UN);
  106. fclose ($fp);
  107. }
  108.  
  109. function file_MoveLineToTop ($filename, $index) {
  110. $line = file_GetLine($filename, $index);
  111. file_DeleteLine($filename, $index);
  112. file_InsertLineOnTop($filename, $line);
  113. }
  114.  
  115. function file_SaveToFile ($filename, $something) {
  116. $fp = fopen ($filename, "w");
  117. while (!flock($fp, LOCK_EX)) { usleep(100000);};
  118. fputs ($fp, $something);
  119. flock($fp, LOCK_UN);
  120. fclose ($fp);
  121. }
  122.  
  123. function file_ReadFromFile ($filename) {
  124. if (filesize($filename) > 0) {
  125. $fp = fopen ($filename, "r");
  126. while (!flock($fp, LOCK_SH)) { usleep(100000);};
  127. $file = fread($fp, filesize ($filename));
  128. flock($fp, LOCK_UN);
  129. fclose ($fp);
  130. return $file;
  131. }
  132. }
  133.  
  134. function file_CreateFile ($filename) { //a czy nie powinnieneś spr. czy już nie istnieje?
  135. $fp = fopen ($filename, "w");
  136. fclose ($fp);
  137. }
  138. ?>
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 6.10.2025 - 03:21