mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-05-10 20:44:28 +09:00
Add streaming options to Storage::read() and Storage::write()
This commit is contained in:
parent
4fa3bf8cfb
commit
36bc83680f
2 changed files with 72 additions and 9 deletions
|
|
@ -148,18 +148,28 @@ class Storage
|
||||||
* Get the content of a file.
|
* Get the content of a file.
|
||||||
*
|
*
|
||||||
* This method returns the content if it exists and is readable.
|
* This method returns the content if it exists and is readable.
|
||||||
* Otherwise, it returns false.
|
* If $stream is true, it will return the content as a stream instead of
|
||||||
|
* loading the entire content in memory. This may be useful for large files.
|
||||||
|
* If the file cannot be opened, this method returns false.
|
||||||
*
|
*
|
||||||
* @param string $filename
|
* @param string $filename
|
||||||
* @return string|false
|
* @param bool $stream (optional)
|
||||||
|
* @return string|resource|false
|
||||||
*/
|
*/
|
||||||
public static function read($filename)
|
public static function read($filename, $stream = false)
|
||||||
{
|
{
|
||||||
$filename = rtrim($filename, '/\\');
|
$filename = rtrim($filename, '/\\');
|
||||||
if (self::exists($filename) && @is_file($filename) && @is_readable($filename))
|
if (self::exists($filename) && @is_file($filename) && @is_readable($filename))
|
||||||
|
{
|
||||||
|
if ($stream)
|
||||||
|
{
|
||||||
|
return @fopen($filename, 'r');
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return @file_get_contents($filename);
|
return @file_get_contents($filename);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -190,10 +200,12 @@ class Storage
|
||||||
/**
|
/**
|
||||||
* Write $content to a file.
|
* Write $content to a file.
|
||||||
*
|
*
|
||||||
|
* If $content is a stream, this method will copy it to the target file
|
||||||
|
* without loading the entire content in memory. This may be useful for large files.
|
||||||
* This method returns true on success and false on failure.
|
* This method returns true on success and false on failure.
|
||||||
*
|
*
|
||||||
* @param string $filename
|
* @param string $filename
|
||||||
* @param string $content
|
* @param string|resource $content
|
||||||
* @param string $mode (optional)
|
* @param string $mode (optional)
|
||||||
* @param int $perms (optional)
|
* @param int $perms (optional)
|
||||||
* @return string|false
|
* @return string|false
|
||||||
|
|
@ -211,9 +223,26 @@ class Storage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$flags = ($mode === 'a') ? (\FILE_APPEND | \LOCK_EX) : (\LOCK_EX);
|
if ($fp = fopen($filename, $mode))
|
||||||
$write_success = @file_put_contents($filename, $content, $flags);
|
{
|
||||||
$result = ($write_success === strlen($content)) ? true : false;
|
flock($fp, \LOCK_EX);
|
||||||
|
if (is_resource($content))
|
||||||
|
{
|
||||||
|
$result = stream_copy_to_stream($content, $fp) ? true : false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$result = fwrite($fp, $content) ? true : false;
|
||||||
|
}
|
||||||
|
fflush($fp);
|
||||||
|
flock($fp, \LOCK_UN);
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@chmod($filename, ($perms === null ? (0666 & ~umask()) : $perms));
|
@chmod($filename, ($perms === null ? (0666 & ~umask()) : $perms));
|
||||||
if (function_exists('opcache_invalidate') && substr($filename, -4) === '.php')
|
if (function_exists('opcache_invalidate') && substr($filename, -4) === '.php')
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -116,20 +116,54 @@ class StorageTest extends \Codeception\TestCase\Test
|
||||||
|
|
||||||
public function testRead()
|
public function testRead()
|
||||||
{
|
{
|
||||||
|
// Simple read test
|
||||||
$this->assertEquals(file_get_contents(__FILE__), Rhymix\Framework\Storage::read(__FILE__));
|
$this->assertEquals(file_get_contents(__FILE__), Rhymix\Framework\Storage::read(__FILE__));
|
||||||
$this->assertFalse(Rhymix\Framework\Storage::read(__FILE__ . '.nonexistent.suffix'));
|
$this->assertFalse(Rhymix\Framework\Storage::read(__FILE__ . '.nonexistent.suffix'));
|
||||||
$this->assertFalse(Rhymix\Framework\Storage::read(__DIR__));
|
$this->assertFalse(Rhymix\Framework\Storage::read(__DIR__));
|
||||||
$this->assertFalse(Rhymix\Framework\Storage::read('/dev/nonexistent'));
|
$this->assertFalse(Rhymix\Framework\Storage::read('/dev/nonexistent'));
|
||||||
|
|
||||||
|
// Stream read test
|
||||||
|
$fp = Rhymix\Framework\Storage::read(__FILE__, true);
|
||||||
|
$this->assertTrue(is_resource($fp));
|
||||||
|
$this->assertEquals(file_get_contents(__FILE__), fread($fp, filesize(__FILE__)));
|
||||||
|
fclose($fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testWrite()
|
public function testWrite()
|
||||||
{
|
{
|
||||||
$testfile = \RX_BASEDIR . 'tests/_output/subdirectory/testfile.txt';
|
$testfile = \RX_BASEDIR . 'tests/_output/subdirectory/testfile.txt';
|
||||||
|
$copyfile = \RX_BASEDIR . 'tests/_output/subdirectory/copyfile.txt';
|
||||||
|
|
||||||
$this->assertFalse(file_exists($testfile));
|
// Simple write test
|
||||||
$this->assertTrue(Rhymix\Framework\Storage::write($testfile, 'foobarbazzjazz'));
|
$this->assertTrue(Rhymix\Framework\Storage::write($testfile, 'foobarbazzjazz'));
|
||||||
$this->assertTrue(file_exists($testfile));
|
$this->assertTrue(file_exists($testfile));
|
||||||
$this->assertEquals('foobarbazzjazz', file_get_contents($testfile));
|
$this->assertEquals('foobarbazzjazz', file_get_contents($testfile));
|
||||||
|
$this->assertEquals(0666 & ~umask(), fileperms($testfile) & 0777);
|
||||||
|
|
||||||
|
// Append test
|
||||||
|
$this->assertTrue(Rhymix\Framework\Storage::write($testfile, 'rhymix', 'a', 0666));
|
||||||
|
$this->assertTrue(file_exists($testfile));
|
||||||
|
$this->assertEquals('foobarbazzjazzrhymix', file_get_contents($testfile));
|
||||||
|
$this->assertEquals(0666, fileperms($testfile) & 0777);
|
||||||
|
|
||||||
|
// Stream copy test
|
||||||
|
$stream = fopen($testfile, 'r');
|
||||||
|
$this->assertTrue(Rhymix\Framework\Storage::write($copyfile, $stream));
|
||||||
|
$this->assertEquals('foobarbazzjazzrhymix', file_get_contents($copyfile));
|
||||||
|
fclose($stream);
|
||||||
|
|
||||||
|
// Stream append test
|
||||||
|
$stream = fopen($testfile, 'r');
|
||||||
|
$this->assertTrue(Rhymix\Framework\Storage::write($copyfile, $stream, 'a'));
|
||||||
|
$this->assertEquals('foobarbazzjazzrhymixfoobarbazzjazzrhymix', file_get_contents($copyfile));
|
||||||
|
fclose($stream);
|
||||||
|
|
||||||
|
// Partial stream append test
|
||||||
|
$stream = fopen($testfile, 'r');
|
||||||
|
fseek($stream, 14);
|
||||||
|
$this->assertTrue(Rhymix\Framework\Storage::write($copyfile, $stream, 'a'));
|
||||||
|
$this->assertEquals('foobarbazzjazzrhymixfoobarbazzjazzrhymixrhymix', file_get_contents($copyfile));
|
||||||
|
fclose($stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testReadWritePHPData()
|
public function testReadWritePHPData()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue