PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/SyracavaPHP/syracava/ext/pear/File.php

http://syracava.googlecode.com/
PHP | 543 lines | 260 code | 67 blank | 216 comment | 43 complexity | 0aab133fe426b3c99bd29aafe5935521 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.0, LGPL-2.1
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * File
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: This source file is subject to version 3.0 of the PHP license
  9. * that is available through the world-wide-web at the following URI:
  10. * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  11. * the PHP License and are unable to obtain it through the web, please
  12. * send a note to license@php.net so we can mail you a copy immediately.
  13. *
  14. * @category File
  15. * @package File
  16. * @author Richard Heyes <richard@php.net>
  17. * @author Tal Peer <tal@php.net>
  18. * @author Michael Wallner <mike@php.net>
  19. * @copyright 2002-2005 The Authors
  20. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  21. * @version CVS: $Id: File.php 125 2009-08-21 01:35:18Z takuji.mezawa $
  22. * @link http://pear.php.net/package/File
  23. */
  24. /**
  25. * Requires PEAR
  26. */
  27. require_once 'PEAR.php';
  28. /**
  29. * The default number of bytes for reading
  30. */
  31. if (!defined('FILE_DEFAULT_READSIZE')) {
  32. define('FILE_DEFAULT_READSIZE', 1024, true);
  33. }
  34. /**
  35. * The maximum number of bytes for reading lines
  36. */
  37. if (!defined('FILE_MAX_LINE_READSIZE')) {
  38. define('FILE_MAX_LINE_READSIZE', 40960, true);
  39. }
  40. /**
  41. * Whether file locks should block
  42. */
  43. if (!defined('FILE_LOCKS_BLOCK')) {
  44. define('FILE_LOCKS_BLOCK', true, true);
  45. }
  46. /**
  47. * Mode to use for reading from files
  48. */
  49. define('FILE_MODE_READ', 'rb', true);
  50. /**
  51. * Mode to use for truncating files, then writing
  52. */
  53. define('FILE_MODE_WRITE', 'wb', true);
  54. /**
  55. * Mode to use for appending to files
  56. */
  57. define('FILE_MODE_APPEND', 'ab', true);
  58. /**
  59. * Use this when a shared (read) lock is required
  60. */
  61. define('FILE_LOCK_SHARED', LOCK_SH | (FILE_LOCKS_BLOCK ? 0 : LOCK_NB), true);
  62. /**
  63. * Use this when an exclusive (write) lock is required
  64. */
  65. define('FILE_LOCK_EXCLUSIVE', LOCK_EX | (FILE_LOCKS_BLOCK ? 0 : LOCK_NB), true);
  66. /**
  67. * Class for handling files
  68. *
  69. * A class with common functions for writing,
  70. * reading and handling files and directories
  71. *
  72. * @author Richard Heyes <richard@php.net>
  73. * @author Tal Peer <tal@php.net>
  74. * @author Michael Wallner <mike@php.net>
  75. * @access public
  76. * @package File
  77. *
  78. * @static
  79. */
  80. class File extends PEAR
  81. {
  82. /**
  83. * Destructor
  84. *
  85. * Unlocks any locked file pointers and closes all filepointers
  86. *
  87. * @access private
  88. */
  89. function _File()
  90. {
  91. File::closeAll();
  92. }
  93. /**
  94. * Handles file pointers. If a file pointer needs to be opened,
  95. * it will be. If it already exists (based on filename and mode)
  96. * then the existing one will be returned.
  97. *
  98. * @access private
  99. * @param string $filename Filename to be used
  100. * @param string $mode Mode to open the file in
  101. * @param mixed $lock Type of lock to use
  102. * @return mixed PEAR_Error on error or file pointer resource on success
  103. */
  104. function _getFilePointer($filename, $mode, $lock = false)
  105. {
  106. $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  107. // Win32 is case-insensitive
  108. if (OS_WINDOWS) {
  109. $filename = strtolower($filename);
  110. }
  111. // check if file pointer already exists
  112. if (!isset($filePointers[$filename][$mode]) ||
  113. !is_resource($filePointers[$filename][$mode])) {
  114. // check if we can open the file in the desired mode
  115. switch ($mode)
  116. {
  117. case FILE_MODE_READ:
  118. if (!preg_match('/^.+(?<!file):\/\//i', $filename) &&
  119. !file_exists($filename)) {
  120. return PEAR::raiseError("File does not exist: $filename");
  121. }
  122. break;
  123. case FILE_MODE_APPEND:
  124. case FILE_MODE_WRITE:
  125. if (file_exists($filename)) {
  126. if (!is_writable($filename)) {
  127. return PEAR::raiseError("File is not writable: $filename");
  128. }
  129. } elseif (!is_writable($dir = dirname($filename))) {
  130. return PEAR::raiseError("Cannot create file in directory: $dir");
  131. }
  132. break;
  133. default:
  134. return PEAR::raiseError("Invalid access mode: $mode");
  135. }
  136. // open file
  137. $filePointers[$filename][$mode] = @fopen($filename, $mode);
  138. if (!is_resource($filePointers[$filename][$mode])) {
  139. return PEAR::raiseError('Failed to open file: ' . $filename);
  140. }
  141. }
  142. // lock file
  143. if ($lock) {
  144. $lock = $mode == FILE_MODE_READ ? FILE_LOCK_SHARED : FILE_LOCK_EXCLUSIVE;
  145. $locks = &PEAR::getStaticProperty('File', 'locks');
  146. if (@flock($filePointers[$filename][$mode], $lock)) {
  147. $locks[] = &$filePointers[$filename][$mode];
  148. } elseif (FILE_LOCKS_BLOCK) {
  149. return PEAR::raiseError("File already locked: $filename");
  150. } else {
  151. return PEAR::raiseError("Could not lock file: $filename");
  152. }
  153. }
  154. return $filePointers[$filename][$mode];
  155. }
  156. /**
  157. * Reads an entire file and returns it.
  158. * Uses file_get_contents if available.
  159. *
  160. * @access public
  161. * @param string $filename Name of file to read from
  162. * @param mixed $lock Type of lock to use
  163. * @return mixed PEAR_Error if an error has occured or a string with the contents of the the file
  164. */
  165. function readAll($filename, $lock = false)
  166. {
  167. if (false === $file = @file_get_contents($filename)) {
  168. return PEAR::raiseError("Cannot read file: $filename");
  169. }
  170. return $file;
  171. }
  172. /**
  173. * Returns a specified number of bytes of a file.
  174. * Defaults to FILE_DEFAULT_READSIZE. If $size is 0, all file will be read.
  175. *
  176. * @access public
  177. * @param string $filename Name of file to read from
  178. * @param integer $size Bytes to read
  179. * @param mixed $lock Type of lock to use
  180. * @return mixed PEAR_Error on error or a string which contains the data read
  181. * Will also return false upon EOF
  182. */
  183. function read($filename, $size = FILE_DEFAULT_READSIZE, $lock = false)
  184. {
  185. static $filePointers;
  186. if ($size == 0) {
  187. return File::readAll($filename, $lock);
  188. }
  189. if (!isset($filePointers[$filename]) ||
  190. !is_resource($filePointers[$filename])) {
  191. $fp = File::_getFilePointer($filename, FILE_MODE_READ, $lock);
  192. if (PEAR::isError($fp)) {
  193. return $fp;
  194. }
  195. $filePointers[$filename] = $fp;
  196. } else {
  197. $fp = $filePointers[$filename];
  198. }
  199. return !feof($fp) ? fread($fp, $size) : false;
  200. }
  201. /**
  202. * Writes the given data to the given filename.
  203. * Defaults to no lock, append mode.
  204. *
  205. * @access public
  206. * @param string $filename Name of file to write to
  207. * @param string $data Data to write to file
  208. * @param string $mode Mode to open file in
  209. * @param mixed $lock Type of lock to use
  210. * @return mixed PEAR_Error on error or number of bytes written to file.
  211. */
  212. function write($filename, $data, $mode = FILE_MODE_APPEND, $lock = false)
  213. {
  214. $fp = File::_getFilePointer($filename, $mode, $lock);
  215. if (PEAR::isError($fp)) {
  216. return $fp;
  217. }
  218. if (false === $bytes = @fwrite($fp, $data, strlen($data))) {
  219. return PEAR::raiseError("Cannot write data: '$data' to file: '$filename'");
  220. }
  221. return $bytes;
  222. }
  223. /**
  224. * Reads and returns a single character from given filename
  225. *
  226. * @access public
  227. * @param string $filename Name of file to read from
  228. * @param mixed $lock Type of lock to use
  229. * @return mixed PEAR_Error on error or one character of the specified file
  230. */
  231. function readChar($filename, $lock = false)
  232. {
  233. return File::read($filename, 1, $lock);
  234. }
  235. /**
  236. * Writes a single character to a file
  237. *
  238. * @access public
  239. * @param string $filename Name of file to write to
  240. * @param string $char Character to write
  241. * @param string $mode Mode to use when writing
  242. * @param mixed $lock Type of lock to use
  243. * @return mixed PEAR_Error on error, or 1 on success
  244. */
  245. function writeChar($filename, $char, $mode = FILE_MODE_APPEND, $lock = false)
  246. {
  247. $fp = File::_getFilePointer($filename, $mode, $lock);
  248. if (PEAR::isError($fp)) {
  249. return $fp;
  250. }
  251. if (false === @fwrite($fp, $char, 1)) {
  252. return PEAR::raiseError("Cannot write data: '$data' to file: '$filename'");
  253. }
  254. return 1;
  255. }
  256. /**
  257. * Returns a line of the file (without trailing CRLF).
  258. * Maximum read line length is FILE_MAX_LINE_READSIZE.
  259. *
  260. * @access public
  261. * @param string $filename Name of file to read from
  262. * @param boolean $lock Whether file should be locked
  263. * @return mixed PEAR_Error on error or a string containing the line read from file
  264. */
  265. function readLine($filename, $lock = false)
  266. {
  267. static $filePointers; // Used to prevent unnecessary calls to _getFilePointer()
  268. if (!isset($filePointers[$filename]) ||
  269. !is_resource($filePointers[$filename])) {
  270. $fp = File::_getFilePointer($filename, FILE_MODE_READ, $lock);
  271. if (PEAR::isError($fp)) {
  272. return $fp;
  273. }
  274. $filePointers[$filename] = $fp;
  275. } else {
  276. $fp = $filePointers[$filename];
  277. }
  278. if (feof($fp)) {
  279. return false;
  280. }
  281. return rtrim(fgets($fp, FILE_MAX_LINE_READSIZE), "\r\n");
  282. }
  283. /**
  284. * Writes a single line, appending a LF (by default)
  285. *
  286. * @access public
  287. * @param string $filename Name of file to write to
  288. * @param string $line Line of data to be written to file
  289. * @param string $mode Write mode, can be either FILE_MODE_WRITE or FILE_MODE_APPEND
  290. * @param string $crlf The CRLF your system is using. UNIX = \n Windows = \r\n Mac = \r
  291. * @param mixed $lock Whether to lock the file
  292. * @return mixed PEAR_Error on error or number of bytes written to file (including appended crlf)
  293. */
  294. function writeLine($filename, $line, $mode = FILE_MODE_APPEND, $crlf = "\n", $lock = false)
  295. {
  296. $fp = File::_getFilePointer($filename, $mode, $lock);
  297. if (PEAR::isError($fp)) {
  298. return $fp;
  299. }
  300. if (false === $bytes = fwrite($fp, $line . $crlf)) {
  301. return PEAR::raiseError("Cannot write data: '$data' to file: '$file'");
  302. }
  303. return $bytes;
  304. }
  305. /**
  306. * This rewinds a filepointer to the start of a file
  307. *
  308. * @access public
  309. * @param string $filename The filename
  310. * @param string $mode Mode the file was opened in
  311. * @return mixed PEAR Error on error, true on success
  312. */
  313. function rewind($filename, $mode)
  314. {
  315. $fp = File::_getFilePointer($filename, $mode);
  316. if (PEAR::isError($fp)) {
  317. return $fp;
  318. }
  319. if (!@rewind($fp)) {
  320. return PEAR::raiseError("Cannot rewind file: $filename");
  321. }
  322. return true;
  323. }
  324. /**
  325. * Closes all open file pointers
  326. *
  327. * @access public
  328. * @return void
  329. */
  330. function closeAll()
  331. {
  332. $locks = &PEAR::getStaticProperty('File', 'locks');
  333. $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  334. // unlock files
  335. for ($i = 0, $c = count($locks); $i < $c; $i++) {
  336. is_resource($locks[$i]) and @flock($locks[$i], LOCK_UN);
  337. }
  338. // close files
  339. if (!empty($filePointers)) {
  340. foreach ($filePointers as $fname => $modes) {
  341. foreach (array_keys($modes) as $mode) {
  342. if (is_resource($filePointers[$fname][$mode])) {
  343. @fclose($filePointers[$fname][$mode]);
  344. }
  345. unset($filePointers[$fname][$mode]);
  346. }
  347. }
  348. }
  349. }
  350. /**
  351. * This closes an open file pointer
  352. *
  353. * @access public
  354. * @param string $filename The filename that was opened
  355. * @param string $mode Mode the file was opened in
  356. * @return mixed PEAR Error on error, true otherwise
  357. */
  358. function close($filename, $mode)
  359. {
  360. $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  361. if (OS_WINDOWS) {
  362. $filename = strToLower($filename);
  363. }
  364. if (!isset($filePointers[$filename][$mode])) {
  365. return true;
  366. }
  367. $fp = $filePointers[$filename][$mode];
  368. unset($filePointers[$filename][$mode]);
  369. if (is_resource($fp)) {
  370. // unlock file
  371. @flock($fp, LOCK_UN);
  372. // close file
  373. if (!@fclose($fp)) {
  374. return PEAR::raiseError("Cannot close file: $filename");
  375. }
  376. }
  377. return true;
  378. }
  379. /**
  380. * This unlocks a locked file pointer.
  381. *
  382. * @access public
  383. * @param string $filename The filename that was opened
  384. * @param string $mode Mode the file was opened in
  385. * @return mixed PEAR Error on error, true otherwise
  386. */
  387. function unlock($filename, $mode)
  388. {
  389. $fp = File::_getFilePointer($filename, $mode);
  390. if (PEAR::isError($fp)) {
  391. return $fp;
  392. }
  393. if (!@flock($fp, LOCK_UN)) {
  394. return PEAR::raiseError("Cacnnot unlock file: $filename");
  395. }
  396. return true;
  397. }
  398. /**
  399. * @deprecated
  400. */
  401. function stripTrailingSeparators($path, $separator = DIRECTORY_SEPARATOR)
  402. {
  403. if ($path === $separator) {
  404. return $path;
  405. }
  406. return rtrim($path, $separator);
  407. }
  408. /**
  409. * @deprecated
  410. */
  411. function stripLeadingSeparators($path, $separator = DIRECTORY_SEPARATOR)
  412. {
  413. if ($path === $separator) {
  414. return $path;
  415. }
  416. return ltrim($path, $separator);
  417. }
  418. /**
  419. * @deprecated Use File_Util::buildPath() instead.
  420. */
  421. function buildPath($parts, $separator = DIRECTORY_SEPARATOR)
  422. {
  423. require_once 'File/Util.php';
  424. return File_Util::buildPath($parts, $separator);
  425. }
  426. /**
  427. * @deprecated Use File_Util::skipRoot() instead.
  428. */
  429. function skipRoot($path)
  430. {
  431. require_once 'File/Util.php';
  432. return File_Util::skipRoot($path);
  433. }
  434. /**
  435. * @deprecated Use File_Util::tmpDir() instead.
  436. */
  437. function getTempDir()
  438. {
  439. require_once 'File/Util.php';
  440. return File_Util::tmpDir();
  441. }
  442. /**
  443. * @deprecated Use File_Util::tmpFile() instead.
  444. */
  445. function getTempFile($dirname = null)
  446. {
  447. require_once 'File/Util.php';
  448. return File_Util::tmpFile($dirname);
  449. }
  450. /**
  451. * @deprecated Use File_Util::isAbsolute() instead.
  452. */
  453. function isAbsolute($path)
  454. {
  455. require_once 'File/Util.php';
  456. return File_Util::isAbsolute($path);
  457. }
  458. /**
  459. * @deprecated Use File_Util::relativePath() instead.
  460. */
  461. function relativePath($path, $root, $separator = DIRECTORY_SEPARATOR)
  462. {
  463. require_once 'File/Util.php';
  464. return File_Util::relativePath($path, $root, $separator);
  465. }
  466. /**
  467. * @deprecated Use File_Util::realpath() instead.
  468. */
  469. function realpath($path, $separator = DIRECTORY_SEPARATOR)
  470. {
  471. require_once 'File/Util.php';
  472. return File_Util::realpath($path, $separator);
  473. }
  474. }
  475. PEAR::registerShutdownFunc(array('File', '_File'));
  476. ?>