文档章节

关于aws S3文件上传的锁问题

o0无忧亦无怖
 o0无忧亦无怖
发布于 2017/02/17 13:35
字数 648
阅读 22
收藏 0

#问题出现情况 由于客户端是(安卓、iOS、PC)多个版本的,因此,要传不同的文件到S3服务器,但是在上传完毕之后,出现了无法删除本地文件的提示 “text file busy”

#问题的分析 text file busy 即文件正忙,因此可能出现的原因有:

1.文件还没有上传完

2.文件被进程锁定了

3.文件资源没有被释放(因为aws的SDK是封装好的,因此当时我相信了他,么有考虑这一点,最后发现居然就是这一点)

#查看官方文档

public Guzzle\Service\Resource\Model putObject( array $args = array() )

$arg是参数

$result = $client->putObject(array(
    'ACL' => 'string',
    'Body' => 'mixed type: string|resource|\Guzzle\Http\EntityBodyInterface',
    // Bucket is required
    'Bucket' => 'string',
    'CacheControl' => 'string',
    'ContentDisposition' => 'string',
    'ContentEncoding' => 'string',
    'ContentLanguage' => 'string',
    'ContentLength' => integer,
    'ContentType' => 'string',
    'Expires' => 'mixed type: string (date format)|int (unix timestamp)|\DateTime',
    'GrantFullControl' => 'string',
    'GrantRead' => 'string',
    'GrantReadACP' => 'string',
    'GrantWriteACP' => 'string',
    // Key is required
    'Key' => 'string',
    'Metadata' => array(
        // Associative array of custom 'string' key names
        'string' => 'string',
        // ... repeated
    ),
    'ServerSideEncryption' => 'string',
    'StorageClass' => 'string',
    'WebsiteRedirectLocation' => 'string',
    'SSECustomerAlgorithm' => 'string',
    'SSECustomerKey' => 'string',
    'SSECustomerKeyMD5' => 'string',
    'SSEKMSKeyId' => 'string',
    'RequestPayer' => 'string',
));

官方示例

$result = $client->putObject(array(
    'Bucket' => $bucket,
    'Key'    => 'data.txt',
    'Body'   => 'Hello!'
));

#强制获取文件返回方式(DEBUG过程) 首先,我们尝试用获取到返回值回调的方式进行判断(我们认为是文件还在上传过程中)。下面是官方的demo:

$result = $client->putObject(array(
    'Bucket'     => $bucket,
    'Key'        => 'data_from_file.txt',
    'SourceFile' => $pathToFile,
    'Metadata'   => array(
        'Foo' => 'abc',
        'Baz' => '123'
    )
));

// We can poll the object until it is accessible
$client->waitUntil('ObjectExists', array(
    'Bucket' => $this->bucket,
    'Key'    => 'data_from_file.txt'
));

然而问题并没有得到解决,但是文件很明显的是上传上去了的。同时,证明了putObject是个同步的操作而不是异步,因为他产生了很明显的延迟。

#继续查阅文档

$client->putObject(array(
    'Bucket' => $bucket,
    'Key'    => 'data_from_stream.txt',
    'Body'   => fopen($pathToFile, 'r+')
));

发现S3上传是可以通过资源或者字符流方式进行上传,因此,修改代码。

    try{
			if(isset($data['SourceFile'])) {
				$data['Body'] = fopen($data['SourceFile'],'r+');
				unset($data['SourceFile']);
			}
			$this->_s3->putObject($data);
			fclose($data['Body']);
		} catch(\Exception $e) {
			return $e->getMessage();
	}

不再相信S3会自动释放文件资源,果然,本地文件已被删除。

#推测

AWS的S3的SDK是没有对文件进行释放,而它内部普遍采用static的方法和类,因此文件释放的时机是由PHP决定。 所以出现了text file busy的错误。

#解决方案

不要相信SDK能处理好一切,对于本地的资源类型和需要上锁的操作交由自己来管理。

© 著作权归作者所有

共有 人打赏支持
下一篇: 2016年终总结
o0无忧亦无怖
粉丝 41
博文 87
码字总数 69632
作品 1
海淀
程序员
私信 提问
Linux服务器通过aws命令行上传文件至S3

目的 Linux服务器通过AWS命令行上传文件至S3 配置 打开你的AWS控制台; 连接你的Linux服务器,按照以下步骤操作; # 安装pip yum -y install python-pip # 安装awscli pip install awscli #...

M玺
2017/05/17
0
0
AWS亚马逊S3云储存怎么批量上传文件夹?用Python吧!

AWS S3 在浏览器没有拖动文件夹上传的功能,手动维护文件实在是太过辛苦了,用Python API吧! AWS S3 才是当今世界上最大的云存储。虽然 S3 服务的对象多为企业用户,你同样可以使用它搭建个...

阿锋zxf
05/16
0
0
如何使用 S3 做为私有 Git 仓库

通常那些网站上的文件内容都是存储在一个git仓库里的.(对于非从事软件行业的人来说,可以把"git"理解为是一个可以让你以逻辑方式保存文件的所有历史变化内容的,用于版本控制的系统).当我要使...

oschina
2014/10/10
4.3K
12
为什么是无服务器计算?第一手AWS lambda测试报告!

摘要:第一手的一步一步的,带你体验亚马逊“函数即服务(function as aservice)”平台。 为什么一名开发者应该使用AWS Lambda?简单一句话的说,AWS Lambda-是另外一种事件驱动方式,“fun...

xiaoli110
06/26
0
0
挖洞经验 看我如何发现苹果公司官网Apple.com的无限制文件上传漏洞

        在前几篇文章中,我分享了亚马逊网站XSS漏洞和Bol.com的开放重定向漏洞,今天我再和大家聊聊不安全的服务器配置问题,很多时候,服务器的错误配置将会导致一些列目录或无限制文...

FreeBuf
07/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

新手也能看懂,消息队列其实很简单

该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 16k)。地址:https://github.com/Snailclimb/JavaGuide. 本文内容思维导图: 消息...

阿里云官方博客
11分钟前
0
0
如何在Chrome浏览器中启动deviceready事件(尝试调试phonegap项目)?

我正在开发PhoneGap应用程序,我希望能够在Chrome中调试它,而不是在电话上调试。但是,我在onGetReady()函数中初始化我的代码,该函数在PhoneGap触发“deviceready”事件时触发。由于Chr...

kisshua
今天
9
0
nginx中部署vue打包后的静态文件

如何在nginx中部署静态资源就不描述了, 请看我的这篇博客 将vue脚手架项目打包后的静态文件放到nginx上, 发现有个问题, 即url上有#, 怎么去掉这个#呢. 1 项目中router的mode 路由的mode要为h...

克虏伯
今天
13
0
JS容易理解错误的地方

在这端代码执行的末尾,你会不会hi变量回事函数中的hi了?你会不会认为这不是按引用传递了? 对值传递和引用传递产生质疑了? 1 var hi = {};2 function sayHello(hi) { ...

器石_
今天
9
0
Java开发学习--MongoDB

之前只学过sql,第一次使用非关系型数据库。以前对于关系型数据库与非关系型数据库的概念很模糊,通过这次的学习对这两者有了一个清晰的概念。 主键 在MongoDB中,主键名叫"_id",如果在生成...

微笑向暖wx
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部