是否可以逐行读取Amazon S3的文件?我希望让人们在某处上传大文件,然后让一些代码(可能在亚马逊上运行)逐行读取他们的文件并用它做一些事情,可能是以地图缩减的多线程方式。或者也许只能一次加载1000行......有什么建议吗?
答案 0 :(得分:1)
Amazon S3确实支持范围请求,但它不是为逐行读取文件而设计的。
然而,看起来Amazon Elastic MapReduce可能非常适合您所寻找的内容。 S3和EC2实例之间的转移将非常快,然后您可以以任何方式分割工作。
答案 1 :(得分: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);
}
?>
答案 2 :(得分: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包。