[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: бинарно-безопасное очищение файла
dodger778
Здравствуйте, уважаемые Форумчани!
Есть задание записывать информацию в файл, но при перезаписи информации в файле, он наполняется несуществующими символами. Причем чем больше раз сохраняешь инфу, тем больше этих самых символов.

Код:

class cache2{
var $path = "/srv/so23_html/cache/";
var $data;
var $file;
var $key;
//
function __construct(array &$data=null){
if($data)
$this->data = &$data;

if(isset($_COOKIE['cache'])){
$this->key = $_COOKIE['cache'];
$this->path = $this->path.$this->key;
} else {
$this->generateKey();
}
$this->open();
}

function printCache(){
echo "<pre>";
print_r($this->data);
echo "</pre>";
}
//Сохранить
function save(){
file_put_contents($this->path,"");
$data = json_encode($this->data);
fwrite($this->file, $data);
}
//Прочитать данные
function read(){
if($size=fileSize($this->path)){
$data = fread($this->file, $size);
$data = json_decode($data, true);
return $data;
}
}


function delete(){}

//Сгенерировать имя файла
function generateKey(){
$time = time();
$key = $time.$_SERVER['REMOTE_ADDR'];
$this->key = $time."_".md5($key).".cache";
setcookie("cache", $this->key, $time+3600*24*365, $_SERVER['REQUEST_URI'], $_SERVER['HTTP_HOST']);
return $this->path = $this->path.$this->key;
}

//Создать файл
function createCacheFile(){
$this->file = fopen($this->path, "w+");
chmod($this->path, 0755);
}

//Открыть файл
function open(){
if(is_file($this->path))
$this->file = fopen($this->path, "r+");
else
$this->createCacheFile();
}

function __destruct(){
clearstatcache();
}

}



Вызывается это все вот таким вот способом:
$data = array(1,2,3,4,5,6,7, "test"=>3);
$cache = new cache2($data);

$cache->save();

$data = array('test'=>1,'test1'=>2);

$cache->save();
$cache->save();
$cache->save();
$cache->save();

print_r($cache->read());

Я с ума схожу уже. Дело то все в очистке файла. В функции save() очистка происходит функцией:
file_put_contents()
При использовании функции:
ftruncate()
преследует тот же результат, файл наполняется символами с кодом 0x000. Нда ... в файл по факту записывается 132 байта, хотя информации я пытаюсь записать на 20. Причем чем больше вызываешь метод save() тем больше размер файла. Может есть другие способы очистить файл? Проверял скрипт на 2х машинах, обе линукс, и на обоих один и тот результат.
Спасибо всем кто откликнется и поможет разобраться с данной проблемой.



Спустя 2 часа, 42 минуты, 44 секунды (6.08.2012 - 12:30) I++ написал(а):
Не пробывали менять

  function save(){
file_put_contents($this->path,"");
$data = json_encode($this->data);
fwrite($this->file, $data);
}


на
function save(){
ftruncate($this->file, 0);
$data = json_encode($this->data);
fwrite($this->file, $data);
}

Спустя 15 минут, 48 секунд (6.08.2012 - 12:46) dodger778 написал(а):
I++
Да пробовал, по правде говоря file_put_contents() тут стоит просто от безысходности, ради эксперимента т.к. при использовании ftruncate() меня преследует тот же результат.

Спустя 7 минут, 25 секунд (6.08.2012 - 12:53) I++ написал(а):
Попробуй заменить

$this->file = fopen($this->path, "r+");


на

$this->file = fopen($this->path, "a+");


P.S ftruncate оставь, тот, что я описал

Линь какой? И FS?

Спустя 1 час, 3 минуты, 21 секунда (6.08.2012 - 13:57) dodger778 написал(а):
ftruncate оставлен, спасибо.
Ubuntu 12.04 LTS.
FS (Если файловая система) ext4, если я конечно правильно понял. Спасибо.

Спустя 17 минут (6.08.2012 - 14:14) I++ написал(а):
Странно, на ext4 должно нормально работать, но мне кажется, все таки дело в O_APPEND сишной open.

С флагом "a+" заработало?

Спустя 45 минут, 14 секунд (6.08.2012 - 14:59) dodger778 написал(а):
Да, спасибо большое, с флагом "a+" работает, только print_r() теперь не хочет печатать. Ну да ладно, думаю то с этим разберусь.

Спустя 13 минут, 52 секунды (6.08.2012 - 15:13) dodger778 написал(а):
В общем итог:
Такая же проблема может преследовать на других ОС, на centOS 5 и Ubuntu 12 точно.
При очищении файла через функции file_put_contents() и ftruncate() c последующей в него записью, в файл записывается мусор состоящий из нулевых байтов (0x000).
Подобное возникает при работе с функцией fopen() через флаг "w+" или "r+".
Чтобы такого не происходило нужно работать через флаг "a+"
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.