SitePoint Sponsor |
|
User Tag List
Results 1 to 7 of 7
Hybrid View
-
Apr 20, 2009, 05:18 #1
Problems with the file functions.
I have a class, File, which handles file functions... I have File::replace($old, $new); which is working fine, but when I go to File::read(); after replace() is called, it wont output the file contents... Any ideas as to why?
Code PHP:public function replace($old, $new, $all = false) { $pointer = $this->find($old, true); $tmp_name = $this->file.".tmp"; $tmp = new File($tmp_name, $this->binary); $tmp->truncate(0); $tmp->write($this->read(($pointer + strlen($old)), $this->size)); $this->truncate($pointer); $this->write($new); $this->write($tmp->read()); $tmp->delete(); if ($all && strpos($this->read(), $old)) { return $this->replace($old, $new, $all); } else { return true; } } $f = new File("file.txt"); $f->truncate(0); $f->write("some text."); echo $f->read(); $f->replace("text", "more text"); echo $f->read();
there is no output... But file.txt when opened in a text editor says "some more text"
Any help would be greatly appreciated.
Also, I am reloading the file stream... I thought maybe that would do it, but nothing...
Code php:public function write($data, $pos = null) { // calls File::reloadFile() after fwrite(); } public function truncate($from = 0, $to = null) { // calls File::reloadFile() after ftruncate(); } private function reloadFile() { fclose($this->fp); $mode = "a+"; if ($this->binary) { $mode .= "b"; } $this->fp = fopen($this->file, $mode); $this->details(null, true); }
- the lid is off the maple syrup again!
-
Apr 20, 2009, 09:06 #2
- Join Date
- Jul 2008
- Posts
- 5,757
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Could you post the entire class?
-
Apr 20, 2009, 16:58 #3
The class is 313 lines, so here are the methods being used:
PHP Code:class File {
public function __construct($file, $binary = FILE_NOT_BINARY) {
$this->file = $file;
$this->binary = $binary;
if (!Open_Files::open($this->file)) {
$this->kill("File '".$this->file."' is already loaded.");
}
if (!$this->exists()) {
$this->error("File '".$this->file."' does not exist.");
}
$mode = "a+";
if ($this->binary) {
$mode .= "b";
}
if (($this->fp = @fopen($this->file, $mode)) === false) {
$this->error("File could not be opened or created. Please check file/folder permissions.");
}
$this->details();
}
/***/
public function read($from = 0, $to = null) {
if (!is_int($from)) {
$this->error("File::read(\$from) must be an int.");
}
$this->pointer($from);
if (is_null($to)) {
$data = "";
do {
$data .= @fread($this->fp, 4096);
} while (!feof($this->fp));
} else {
if (!is_int($to)) {
$this->error("File::read(\$to) must be an int.");
}
$data = @fread($this->fp, $to);
}
return $data;
}
public function find($data, $pointer = false, $reset = false) {
static $offset = 0;
if ($reset) {
$offset = 0;
}
if (($pos = strpos($this->read(), $data, $offset)) !== false) {
$offset++;
return (!$pointer) ? true : $pos;
} else {
return false;
}
}
public function write($data, $pos = null) {
if (!is_null($pos) && !is_int($pos)) {
$this->error("File::write(\$pos) must be an int.");
}
if (!is_null($pos)) {
$this->pointer($pos);
}
if (!empty($data) && (strlen($data) != 0)) {
@fwrite($this->fp, $data);
$this->reloadFile();
}
}
public function replace($old, $new, $all = false) {
$pointer = $this->find($old, true);
$tmp_name = $this->file.".tmp";
$tmp = new File($tmp_name, $this->binary);
$tmp->truncate(0);
$tmp->write($this->read(($pointer + strlen($old)), $this->size));
$this->truncate($pointer);
$this->write($new.$tmp->read());
$tmp->delete();
if ($all && strpos($this->read(), $old)) {
return $this->replace($old, $new, $all);
} else {
return true;
}
}
public function truncate($from = 0) {
if (!is_int($from)) {
$this->error("File::truncate(\$from) must be an int.");
}
if ($from > $this->size) {
$from = $this->size;
}
$this->pointer($from);
@ftruncate($this->fp, $from);
$this->reloadFile();
}
public function delete() {
$this->unlock();
@fclose($this->fp);
@ulink($this->file);
$this->__destruct();
}
private function reloadFile() {
fclose($this->fp);
$mode = "a+";
if ($this->binary) {
$mode .= "b";
}
$this->fp = fopen($this->file, $mode);
$this->details(null, true);
}
/***/
private function __destruct() {
Open_Files::close($this->file);
if (is_resource($this->fp)) {
@fclose($this->fp);
}
}
}
- the lid is off the maple syrup again!
-
Apr 20, 2009, 22:06 #4
- Join Date
- Jul 2008
- Posts
- 5,757
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I was hoping to be able to run the code to make debugging easier, but it's still incomplete, and altered. My guess would be the undisclosed position() method doesn't properly fseek() on the fp. Without a fseek() or rewind(), you will be reading from the end of the file due to using a+ mode.
-
Apr 21, 2009, 00:45 #5
File:
ointer runs fseek()
PHP Code:private function pointer($offset = null) {
if (is_null($offset)) {
return ftell($this->fp);
} else {
return fseek($this->fp, $offset);
}
}
PHP Code:
define("FILE_NOT_BINARY", 0);
define("FILE_IS_BINARY", 1);
class File {
protected $file;
protected $size = -1;
protected $details = array();
private $fp = false;
private $locked = false;
private $binary = false;
private $debug = true;
public function __construct($file, $binary = FILE_NOT_BINARY) {
$this->file = $file;
$this->binary = $binary;
if (!Open_Files::open($this->file)) {
$this->kill("File '".$this->file."' is already loaded.");
}
if (!$this->exists()) {
$this->error("File '".$this->file."' does not exist.");
}
$mode = "a+";
if ($this->binary) {
$mode .= "b";
}
if (($this->fp = @fopen($this->file, $mode)) === false) {
$this->error("File could not be opened or created. Please check file/folder permissions.");
}
$this->details();
}
public function __destruct() {
Open_Files::close($this->file);
if (is_resource($this->fp)) {
@fclose($this->fp);
}
}
public function debug($debug) {
$this->debug = $debug;
}
public function details($detail = null, $reload = false) {
if (is_null($detail)) {
if (empty($this->details) || $reload) {
$pathinfo = pathinfo($this->file);
$details = array();
$details['filename'] = $pathinfo['basename'];
$details['extension'] = $pathinfo['extension'];
$details['filesize'] = filesize($this->file);
$details['directory'] = $pathinfo['dirname'];
$details['created'] = filectime($this->file);
$details['accessed'] = fileatime($this->file);
$details['modified'] = filemtime($this->file);
$details['md5_sum'] = md5_file($this->file);
$details['sha1_sum'] = sha1_file($this->file);
$this->details = $details;
$this->size = $this->details['filesize'];
}
} else {
if (in_array($detail, $this->details)) {
return $this->details[$detail];
} else {
$this->alert("The file detail requested was not available.");
}
}
}
public function permissions($mode) {
if (!@chmod($this->file, $mode)) {
$this->alert("The file permissions are not allowed to be change.");
}
}
public function read($from = 0, $to = null) {
if (!is_int($from)) {
$this->error("Supplied arguments for File::read() must be ints.");
}
$this->pointer($from);
if (is_null($to)) {
$data = "";
do {
$data .= @fread($this->fp, 4096);
} while (!feof($this->fp));
} else {
if (!is_int($to)) {
$this->error("Supplied arguments for File::read() must be ints.");
}
$data = @fread($this->fp, $to);
}
return $data;
}
public function find($data, $pointer = false, $reset = false) {
static $offset = 0;
if ($reset) {
$offset = 0;
}
if (($pos = strpos($this->read(), $data, $offset)) !== false) {
$offset++;
return (!$pointer) ? true : $pos;
} else {
return false;
}
}
public function write($data, $pos = null) {
if (!is_null($pos) && !is_int($pos)) {
$this->error("Supplied argument (\$pos) for File::write() must be an int.");
}
if (!is_null($pos)) {
$this->pointer($pos);
}
if (!empty($data) && (strlen($data) != 0)) {
@fwrite($this->fp, $data);
$this->reloadFile();
}
}
public function replace($old, $new, $all = false) {
$pointer = $this->find($old, true);
$tmp_name = $this->file.".tmp";
$tmp = new File($tmp_name, $this->binary);
$tmp->truncate(0);
$tmp->write($this->read(($pointer + strlen($old)), $this->size));
$this->truncate($pointer);
$this->write($new.$tmp->read());
$tmp->delete();
if ($all && strpos($this->read(), $old)) {
return $this->replace($old, $new, $all);
} else {
return true;
}
}
public function prepend($data) {
return $this->write($data, 0);
}
public function append($data) {
return $this->write($data, $this->size);
}
public function truncate($from = 0) {
if ($from > $this->size) {
$from = $this->size;
}
$this->pointer($from);
@ftruncate($this->fp, $from);
$this->reloadFile();
}
public function erase($from, $to = null) {
if (is_null($to)) {
return $this->truncate($from);
}
if (is_int($from) && is_int($to)) {
$this->error("Supplied arguments for File::erase() must be ints.");
}
$tmp_name = $this->details['directory']."/".$this->details['filename'].".tmp";
$tmp = new File($tmp_name, $this->binary);
$tmp->write($this->read($to));
$this->truncate($from);
$this->write($tmp->read());
$tmp->delete();
}
public function close() {
$this->__destruct();
}
public function saveAs($dest) {
$tmp = new File($dest, $this->binary);
if (is_object($tmp)) {
$tmp->truncate();
$tmp->write($this->read());
$tmp->close();
return true;
} else {
$this->alert("File could not be saved to the new location.");
return false;
}
}
public function copy($dest) {
if (!@copy($this->file, $dest)) {
$this->alert("File could not be copied to the new location.");
return false;
}
return true;
}
public function delete() {
$this->unlock();
@fclose($this->fp);
@ulink($this->file);
$this->__destruct();
}
private function exists() {
return @file_exists($this->file);
}
private function lock($operation = LOCK_EX) {
if (!@flock($this->fp, $operation)) {
$this->kill("File is in use by another source.");
} else {
$this->locked = true;
}
}
private function unlock() {
if ($this->locked) {
if (@flock($this->fp, LOCK_UN)) {
$this->error("File lock could not be released.");
}
$this->locked = false;
}
}
private function pointer($offset = null) {
if (is_null($offset)) {
return ftell($this->fp);
} else {
return fseek($this->fp, $offset);
}
}
private function reloadFile() {
fclose($this->fp);
$mode = "a+";
if ($this->binary) {
$mode .= "b";
}
$this->fp = fopen($this->file, $mode);
$this->details(null, true);
}
private function kill($msg) {
if ($this->debug) {
echo "From: '".$this->file."' : ".$msg." This instance of File has been terminated.\n";
}
$this->__destruct();
}
private function error($msg) {
if ($this->debug) {
throw new File_Exception("From: '".$this->file."' : ".$msg);
}
}
private function alert($msg) {
if ($this->debug) {
echo "Warning From: '".$this->file."' : ".$msg."\n";
}
}
}
class Open_Files {
private static $opened = array();
public function open($file) {
if (in_array($file, self::$opened)) {
return false;
}
self::$opened[$file] = true;
return true;
}
public function close($file) {
if (in_array($file, self::$opened)) {
unset(self::$opened[$file]);
}
}
}
class File_Exception extends RuntimeException {
public function __construct($message, $code = 0, $values = array()) {
if (!empty($values)) {
$message = vsprintf($message, $values);
}
parent::__construct($message, $code);
}
}
- the lid is off the maple syrup again!
-
Apr 21, 2009, 08:35 #6
- Join Date
- Jul 2008
- Posts
- 5,757
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
you typo'd unlink()
-
Apr 21, 2009, 20:38 #7
Well, I know it wasn't unlink() causing the problems. But thanks for letting me know
I have tried it a few times commenting out the $tmp->delete(); in File::replace
- the lid is off the maple syrup again!
Bookmarks