
S3のフォルダオブジェクトはファイルシステムのフォルダとは異なる
Amazon S3 の「フォルダオブジェクト」は一般的なファイルシステムの「フォルダ」と別物らしいので調べてみた。
フォルダオブジェクトとプレフィックス
- フォルダオブジェクト
- オブジェクト名が’/‘で終わる、サイズ0のオブジェクト
- プレフィックス
- オブジェクト名の接頭辞
- ‘/‘で終わる
s3://hoge/fuga/tako/ika.log の場合、
- hoge = バケット名
- fuga/tako/ = ika.log のプレフィックス
- fuga/ と tako/ はフォルダオブジェクトの場合がある
見分け方
AWSのWeb GUIでS3を見るとフォルダオブジェクトとプレフィックスは区別が付かないけど、AWS CLI からなら見分けられる
aws s3 ls <バケット名>/hogehoge/
- サイズ0の名前のないオブジェクトがあったらフォルダオブジェクト
- なかったらプレフィックス
aws s3api head-object --bucket <バケット名> --prefix hogehoge/
- ContentLengthが0だったらフォルダオブジェクト
- フォルダとして見えているのに404が返ってきたらプレフィックス
aws s3api list-objects-v2 --bucket <バケット名> --prefix hogehoge/
- Sizeが0でKeyが/で終わるコンテンツがあったらフォルダオブジェクト
- なかったらプレフィックス
例えば以下は、nissy-lab-testというバケットの hogehoge/ は404が返ってきたのでプレフィックス
user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key hogehoge/
An error occurred (404) when calling the HeadObject operation: Not Found
以下はContentLengthが0で、オプションで渡したキーが「/」で終わっているのでフォルダオブジェクト
user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key hogehoge/
{
"AcceptRanges": "bytes",
"LastModified": "2025-03-19T10:00:00+00:00",
"ContentLength": 0,
"ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"",
"VersionId": "tlTiXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"ContentType": "application/x-directory; charset=UTF-8",
"ServerSideEncryption": "AES256",
"Metadata": {}
}
以下はContentLengthが0だけど、オプションで渡したキーは「/」で終わっていないので通常のオブジェクト
user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key hogehoge
{
"AcceptRanges": "bytes",
"LastModified": "2025-03-19T10:00:00+00:00",
"ContentLength": 0,
"ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"",
"VersionId": "yQj_XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"ContentType": "binary/octet-stream",
"ServerSideEncryption": "AES256",
"Metadata": {}
}
実際に作って試してみる
フォルダオブジェクト
- hogehoge/ というフォルダオブジェクトもプレフィックスも存在しない状態で
user1@server1:~$ aws s3 ls nissy-lab-test/ user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key hogehoge/ An error occurred (404) when calling the HeadObject operation: Not Found user1@server1:~$ aws s3api list-objects-v2 --bucket nissy-lab-test --prefix hogehoge/ { "RequestCharged": null }
- フォルダオブジェクト hogehoge/ を作る
user1@server1:~$ aws s3api put-object --bucket nissy-lab-test --key hogehoge/ { "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "ServerSideEncryption": "AES256", "VersionId": "u2ojXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
- オブジェクト hogehoge/hoge.txt を作る
user1@server1:~$ aws s3api put-object --bucket nissy-lab-test --key hogehoge/hoge.txt { "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "ServerSideEncryption": "AES256", "VersionId": "1W58XXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
- hogehoge/ はフォルダオブジェクトであり、 hogehoge/hoge.txt はオブジェクトである
user1@server1:~$ aws s3 ls nissy-lab-test/ PRE hogehoge/ user1@server1:~$ aws s3 ls nissy-lab-test/hogehoge/ 2025-03-19 19:00:00 0 2025-03-19 19:00:00 0 hoge.txt user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key hogehoge/ { "AcceptRanges": "bytes", "LastModified": "2025-03-19T10:00:00+00:00", "ContentLength": 0, "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "VersionId": "J3itXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "ContentType": "binary/octet-stream", "ServerSideEncryption": "AES256", "Metadata": {} } user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key hogehoge/hoge.txt { "AcceptRanges": "bytes", "LastModified": "2025-03-19T10:00:00+00:00", "ContentLength": 0, "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "VersionId": "1W58XXXXXXXXXXXXXXXXXXXXXXXXXXXX", "ContentType": "binary/octet-stream", "ServerSideEncryption": "AES256", "Metadata": {} } user1@server1:~$ aws s3api list-objects-v2 --bucket nissy-lab-test --prefix hogehoge/ { "Contents": [ { "Key": "hogehoge/", "LastModified": "2025-03-19T00:00:00+00:00", "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "ChecksumAlgorithm": [ "CRC64NVME" ], "Size": 0, "StorageClass": "STANDARD" }, { "Key": "hogehoge/hoge.txt", "LastModified": "2025-03-19T00:00:00+00:00", "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "ChecksumAlgorithm": [ "CRC64NVME" ], "Size": 0, "StorageClass": "STANDARD" } ], "RequestCharged": null }
- hogehoge/ はフォルダオブジェクトなので、WebGUIからフォルダを作成できない。
- フォルダオブジェクトを削除しても hogehoge/hoge.txt のプレフィックスとして残る。
user1@server1:~$ aws s3 rm s3://nissy-lab-test/hogehoge/ delete: s3://nissy-lab-test/hogehoge/ user1@server1:~$ aws s3 ls nissy-lab-test/ PRE hogehoge/ user1@server1:~$ aws s3 ls nissy-lab-test/hogehoge/ 2025-03-19 19:00:00 0 hoge.txt user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key hogehoge/ An error occurred (404) when calling the HeadObject operation: Not Found user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key hogehoge/hoge.txt { "AcceptRanges": "bytes", "LastModified": "2025-03-19T10:00:00+00:00", "ContentLength": 0, "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "VersionId": "1W58XXXXXXXXXXXXXXXXXXXXXXXXXXXX", "ContentType": "binary/octet-stream", "ServerSideEncryption": "AES256", "Metadata": {} }
- フォルダオブジェクトとしての hogehoge/ は削除したので、WebGUIからフォルダを作成できる。
プレフィックス
- fugafuga/ というフォルダオブジェクトもプレフィックスも存在しない
user1@server1:~$ aws s3 ls nissy-lab-test PRE hogehoge/ user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key fugafuga/ An error occurred (404) when calling the HeadObject operation: Not Found user1@server1:~$ aws s3api list-objects-v2 --bucket nissy-lab-test --prefix fugafuga/ { "RequestCharged": null }
- オブジェクト fugafuga/fuga.txt を作る
user1@server1:~$ aws s3api put-object --bucket nissy-lab-test --key fugafuga/fuga1.txt { "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "ServerSideEncryption": "AES256", "VersionId": "8nGoXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
- fugafuga/ はプレフィックスであり、 fugafuga/fuga.txt はオブジェクトである
user1@server1:~$ aws s3 ls nissy-lab-test/ PRE fugafuga/ PRE hogehoge/ user1@server1:~$ aws s3 ls nissy-lab-test/fugafuga/ 2025-03-19 19:10:00 0 fuga1.txt user1@server1:~$ aws s3api head-object --bucket nissy-lab-test --key fugafuga/ An error occurred (404) when calling the HeadObject operation: Not Found user1@server1:~$ aws s3api list-objects-v2 --bucket nissy-lab-test --prefix fugafuga/ { "Contents": [ { "Key": "fugafuga/fuga1.txt", "LastModified": "2025-03-19T19:10:00+00:00", "ETag": "\"d41dXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"", "ChecksumAlgorithm": [ "CRC64NVME" ], "Size": 0, "StorageClass": "STANDARD" } ], "RequestCharged": null }
- fugafuga/ はプレフィックスなので、WebGUIからフォルダを作成できる。
- 再び fugafuga/ を削除してただのプレフィックスにすることもできる。
user1@server1:~$ aws s3 rm s3://nissy-lab-test/fugafuga/ delete: s3://nissy-lab-test/fugafuga/ user1@server1:~$ aws s3 ls nissy-lab-test/fugafuga/ 2025-03-19 19:10:00 0 fuga1.txt