是否可以使用 Amazon S3 逐行读取文件?我希望让人们在某处上传大文件,然后让一些代码(可能在亚马逊上运行)逐行读取他们的文件并对其进行处理,可能是以减少地图的多线程方式。或者也许只能一次加载 1000 行......有什么建议吗?
anon
问问题
3435 次
3 回答
1
Amazon S3 确实支持范围请求,但它并非旨在逐行读取文件。
但是,看起来Amazon Elastic MapReduce可能非常适合您的需求。S3 和使用的 EC2 实例之间的传输将非常快,然后您可以以任何您喜欢的方式分配工作。
于 2011-04-11T07:18:27.187 回答
0
这是 PHP 中的一个示例片段,它似乎可以满足您的要求(获取 file.txt 中的前 1000 行并将它们连接起来)。这有点遗憾,但这个想法可以用其他语言或使用其他技术来实现。关键是要像对待任何其他文件系统(如 Windows 或 linux)一样对待 S3,唯一的区别是您使用 S3 密钥凭据并将文件路径设置为 s3://your_directory_tree/your_file.txt":
<?php
set_time_limit(0);
include("gs3.php");
/* fake keys!, please put yours */
define('S3_KEY', 'DA5S4D5A6S4D');
define('S3_PRIVATE','adsadasd');
$f = fopen('s3://mydir/file.txt', 'r');
$c = "";
$d = 0;
$handle = @fopen('s3://mydir/file.txt', "r");
if ($handle) {
while (($buffer = fgets($handle)) !== false && $d < 1000) {
$c .= $buffer; /* concatenate the string (newlines attached)*/
$d += 1; /* increment the count*?
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
else{
print "$c"
}
fclose($handle);
}
?>
于 2011-04-11T23:13:13.677 回答
0
下面是一个使用 PHP 7 和 Laravel 5 如何从 Amazon S3 中逐行读取文件的简单示例:
S3StreamReader.php
<?php
declare(strict_types=1);
namespace App\Helpers\Json;
use App\Helpers\S3StreamFactory;
use Generator;
use SplFileObject;
final class S3StreamReader
{
/**
* @var \App\Helpers\S3StreamFactory
*/
private $streamFactory;
/**
* @param \App\Helpers\S3StreamFactory $s3StreamFactory
*/
public function __construct(S3StreamFactory $s3StreamFactory)
{
$this->streamFactory = $s3StreamFactory;
}
/**
* @param string $filename
* @return \Generator
*/
public function get(string $filename): Generator
{
$file = new SplFileObject($this->streamFactory->create($filename), 'r');
while (!$file->eof()) {
yield $file->fgets();
}
}
}
S3StreamFactory.php
<?php
declare(strict_types=1);
namespace App\Helpers;
use League\Flysystem\AwsS3v3\AwsS3Adapter;
final class S3StreamFactory
{
/**
* @var \League\Flysystem\AwsS3v3\AwsS3Adapter
*/
private $adapter;
/**
* @param \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter
*/
public function __construct(AwsS3Adapter $adapter)
{
$this->adapter = $adapter;
$adapter->getClient()->registerStreamWrapper();
}
/**
* @param string $filename
* @return string
*/
public function create(string $filename): string
{
return "s3://{$this->adapter->getBucket()}/{$filename}";
}
}
使用示例:
$lines = (new S3JsonReader(new S3StreamFactory(Storage::disk('s3')->getAdapter())))->get($sourceFile);
while ($lines->valid()) {
$line = $lines->current();
// do something with the current line...
$lines->next();
}
即使你不使用 Laravel,你仍然可以使用这段代码,因为 Laravel 只使用了 League /flysystem-aws-s3-v3包。
于 2018-06-23T15:39:42.533 回答