2

是否可以使用 Amazon S3 逐行读取文件?我希望让人们在某处上传大文件,然后让一些代码(可能在亚马逊上运行)逐行读取他们的文件并对其进行处理,可能是以减少地图的多线程方式。或者也许只能一次加载 1000 行......有什么建议吗?

4

3 回答 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 回答