{"id":3258,"date":"2021-06-26T22:23:52","date_gmt":"2021-06-26T14:23:52","guid":{"rendered":"http:\/\/123.57.164.21\/?p=3258"},"modified":"2021-06-27T16:17:00","modified_gmt":"2021-06-27T08:17:00","slug":"ibm-storage-%e5%ad%98%e5%82%a8%e5%a4%a7%e5%af%b9%e8%b1%a1","status":"publish","type":"post","link":"https:\/\/92it.top\/?p=3258","title":{"rendered":"IBM Storage  \u5b58\u50a8\u5927\u5bf9\u8c61"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-72-1024x412.png\" alt=\"\" class=\"wp-image-3260\" width=\"607\" height=\"243\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-1024x412.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-300x121.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-768x309.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-1536x618.png 1536w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-2048x824.png 2048w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-830x334.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-230x93.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-350x141.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-72-480x193.png 480w\" sizes=\"(max-width: 607px) 100vw, 607px\" \/><\/figure><\/div>\n\n\n\n<p>IBM Storage \u5b58\u50a8\u5927\u5bf9\u8c61\u5206\u5757\u4e0a\u4f20\uff0c\u539f\u7406\u6bd4\u8f83\u7b80\u5355\uff0c\u5c31\u662f\u5728\u5ba2\u6237\u7aef\u628a\u9700\u8981\u4e0a\u4f20\u7684\u5927\u6587\u4ef6\u5206\u5272\u6210\u5757\uff0c\u7136\u540e\u5e76\u884c\u4e0a\u4f20\u5230IBM Storage\u4e2d\uff0c\u5f53\u6240\u6709\u7684\u5927\u6587\u4ef6\u90fd\u4e0a\u4f20\u6210\u529f\u4ee5\u540e\uff0c\u5ba2\u6237\u7aef\u7ed9IBM Storage\u53d1\u51fa\u4e0a\u4f20\u5b8c\u6210\u7684\u4fe1\u53f7\uff0cIBM Storage\u4f1a\u5b8c\u6210\u5757\u6587\u4ef6\u7684\u5408\u5e76\uff0c\u5e76\u663e\u793a\u5728IBM Storage\u4e2d\u3002<\/p>\n\n\n\n<p>\u5b98\u65b9\u6587\u6863\uff1a<a href=\"https:\/\/cloud.ibm.com\/docs\/cloud-object-storage\/basics?topic=cloud-object-storage-large-objects\">https:\/\/cloud.ibm.com\/docs\/cloud-object-storage\/basics?topic=cloud-object-storage-large-objects<\/a><\/p>\n\n\n\n<p>IBM Storage\u652f\u6301\u5927\u5bf9\u8c61\u5206\u5757\u4e0a\u4f20\u3002\u8fd9\u6837\u7684\u6709\u5f88\u591a\u597d\u5904\uff1a<\/p>\n\n\n\n<ul><li>\u6587\u4ef6\u5206\u5757\u4e4b\u95f4\u53ef\u4ee5\u6309\u4efb\u610f\u987a\u5e8f\u72ec\u7acb\u5730\u3001\u5e76\u884c\u4e0a\u4f20\uff0c\u52a0\u5feb\u4e0a\u4f20\u7684\u901f\u5ea6\u3002<\/li><li>\u5df2\u5b8c\u6210\u7684\u5206\u5757\uff0c\u4f1a\u6682\u65f6\u50a8\u5b58\u5728IBM Storage\u4e2d\uff0c\u8fd9\u6837\u5982\u679c\u4e0a\u4f20\u8fc7\u7a0b\u4e2d\u51fa\u9519\uff0c\u53ea\u9700\u8981\u7eed\u4f20\u672a\u5b8c\u6210\u7684\u6587\u4ef6\u5757\u5c31\u53ef\u4ee5\u4e86\u3002<\/li><li>\u7f51\u7edc\u4e2d\u65ad\u4e0d\u4f1a\u5bfc\u81f4\u5927\u578b\u4e0a\u4f20\u64cd\u4f5c\u5931\u8d25\uff0c\u5728\u4e00\u6bb5\u65f6\u95f4\u5185\u4e0a\u4f20\u53ef\u4ee5\u6682\u505c\u5e76\u91cd\u65b0\u542f\u52a8\u3002<br><\/li><\/ul>\n\n\n\n<p>PS\uff1a\u5206\u5757\u4e0a\u4f20\u4ec5\u53ef\u7528\u4e8e\u5927\u4e8e 5 MB \u7684\u5bf9\u8c61\u3002\u5bf9\u4e8e\u5c0f\u4e8e 50 GB \u7684\u5bf9\u8c61\uff0c\u5efa\u8bae\u7684\u5206\u5757\u5927\u5c0f\u4e3a 20 MB \u5230 100 MB\uff0c\u4ee5\u5b9e\u73b0\u6700\u4f73\u6027\u80fd\u3002\u5bf9\u4e8e\u66f4\u5927\u7684\u5bf9\u8c61\uff0c\u53ef\u4ee5\u589e\u5927\u5206\u5757\u5927\u5c0f\uff0c\u800c\u4e0d\u4f1a\u5bf9\u6027\u80fd\u4ea7\u751f\u91cd\u5927\u5f71\u54cd\u3002\u5206\u5757\u4e0a\u4f20\u9650\u5236\u4e3a\u5206\u5757\u6570\u4e0d\u8d85\u8fc7 10,000 \u4e2a\uff0c\u6bcf\u4e2a\u5206\u5757 5 GB\uff0c\u6700\u5927\u5bf9\u8c61\u5927\u5c0f\u4e3a 10 TB\u3002<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-74-1024x89.png\" alt=\"\" class=\"wp-image-3275\" width=\"750\" height=\"66\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74-1024x89.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74-300x26.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74-768x67.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74-1536x133.png 1536w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74-830x72.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74-230x20.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74-350x30.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74-480x42.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-74.png 1546w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-75-1024x141.png\" alt=\"\" class=\"wp-image-3276\" width=\"758\" height=\"104\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-75-1024x141.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-75-300x41.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-75-768x106.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-75-830x114.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-75-230x32.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-75-350x48.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-75-480x66.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-75.png 1528w\" sizes=\"(max-width: 758px) 100vw, 758px\" \/><\/figure><\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>\u5173\u4e8e\u5206\u5757\u4e0a\u4f20\uff0cIBM Cloud\u63d0\u4f9b\u4e86&nbsp;REST API \u548c SDK(Nodejs, Python, Java, Go)\u7b49\u7b49\u3002\u672c\u6587\u7684\u4ee5IOS\u5f00\u53d1\u4e2d\uff0cSwift\u7528 REST API\u505a\u4e3a\u4f8b\u5b50\u3002<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">\u5206\u5757\u4e0a\u4f20\u5bf9\u8c61\u5206\u4e3a\u4e94\u4e2a\u9636\u6bb5\uff1a<\/h5>\n\n\n\n<h5 class=\"wp-block-heading\">1. \u751f\u6210Bearer Token<\/h5>\n\n\n\n<p>\u8981\u60f3\u4f7f\u7528IBM Storage\u7684API\uff0c \u9996\u5148\u8981\u53d6\u5f97Bearer Token\uff0c\u9996\u5148\u8981\u5229\u7528Rest Api\u521b\u5efa\u4e00\u4e2a\u3002<\/p>\n\n\n\n<p>\u53e6\u5916\uff0capikey\u9700\u8981\u9884\u5148\u5728IBM Storage\u670d\u52a1\u51ed\u8bc1\u4e2d\u83b7\u5f97\u3002<\/p>\n\n\n\n<p>\u751f\u6210Bearer Token\u7684Swift\u65b9\u6cd5\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class func createBearerToken(completion: @escaping ([String: Any]) -> Void) {\n\n        guard let url = URL(string: \"https:\/\/iam.cloud.ibm.com\/identity\/token\") else { return }\n\n        var request = URLRequest(url: url)\n        \/\/ Http POST\u63d0\u51fa\u3002\n        request.httpMethod = \"POST\"\n\n         \/\/ Http Header\u8bbe\u7f6e\u4e0b\u9762\u4e24\u4e2a\u5c5e\u6027\u3002\n        request.addValue(\"application\/json\", forHTTPHeaderField: \"Accept\")\n        request.addValue(\"application\/x-www-form-urlencoded\", forHTTPHeaderField: \"Content-Type\")\n        \n        \/\/ storageApiKey\u9700\u8981\u4eceStorage\u670d\u52a1\u51ed\u8bc1\u4e2d\u83b7\u5f97\n        \/\/ \u7f16\u8f91\u53c2\u6570\u5b57\u7b26\u4e32\uff0c\u505a\u4e3abody\u7684\u4e00\u90e8\u5206\n        let data: Data = \"apikey=\\(storageApiKey)&amp;response_type=cloud_iam&amp;grant_type=urn:ibm:params:oauth:grant-type:apikey\".data(using: .utf8)!\n        request.httpBody = data\n\n        let urlconfig = URLSessionConfiguration.default\n        let session = URLSession(configuration: urlconfig, delegate: nil, delegateQueue: OperationQueue.main)\n\n        session.dataTask(with: request) { (data, response, error) in\n\n            var resultArray: [String: Any] = [:]\n            if let response = response {\n                print(response)\n            }\n\n            guard let data = data else { return }\n            if let jsonObject = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) {\n                if let dicObject = jsonObject as? NSDictionary {\n                    if dicObject[\"errorCode\"] != nil {\n                        resultArray.updateValue(dicObject[\"errorDetails\"]!, forKey: \"message\")\n                    } else {\n                        resultArray.updateValue(dicObject[\"access_token\"]!, forKey: \"access_token\")\n                    }\n                    DispatchQueue.main.async {\n                        completion(resultArray)\n                    }\n                }\n            }\n        }.resume()\n    }<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\u8fd4\u56de\u7ed3\u679c\uff1a\n{\n    \"access_token\" = \"eyJraWQiOiIyMDIxMDYxOTE4xxxxx\";\n    expiration = 1624711576;\n    \"expires_in\" = 3600;\n    \"refresh_token\" = \"not_supported\";\n    scope = \"ibm openid\";\n    \"token_type\" = Bearer;\n}<\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">2. \u901a\u8fc7Rest Api \u521b\u5efaUploadId<\/h5>\n\n\n\n<p>\u6bcf\u4e2a\u4e0a\u4f20\u6587\u4ef6\u4f1a\u5bf9\u5e94\u4e00\u4e2aUploadId\uff0c\u8fd9\u4e2aUploadId\u901a\u8fc7Rest APi\u5411IBM Storage\u8bf7\u6c42\u3002<\/p>\n\n\n\n<p>\u5411IBM Storage\u53d1\u51fa\u4f7f\u7528\u67e5\u8be2\u53c2\u6570&nbsp;<code>upload<\/code>&nbsp;\u7684&nbsp;<code>POST<\/code>&nbsp;\u8bf7\u6c42\u4f1a\u521b\u5efa\u65b0\u7684&nbsp;<code>UploadId<\/code>&nbsp;\u503c\uff0c\u7136\u540e\u8981\u4e0a\u4f20\u7684\u5bf9\u8c61\u7684\u6bcf\u4e2a\u5206\u5757\u90fd\u4f1a\u5f15\u7528\u6b64\u503c\u3002<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-76-1024x342.png\" alt=\"\" class=\"wp-image-3279\" width=\"694\" height=\"231\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76-1024x342.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76-300x100.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76-768x256.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76-1536x513.png 1536w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76-830x277.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76-230x77.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76-350x117.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76-480x160.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-76.png 1606w\" sizes=\"(max-width: 694px) 100vw, 694px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-77-1024x512.png\" alt=\"\" class=\"wp-image-3281\" width=\"690\" height=\"345\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77-1024x512.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77-300x150.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77-768x384.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77-1536x768.png 1536w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77-830x415.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77-230x115.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77-350x175.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77-480x240.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-77.png 1568w\" sizes=\"(max-width: 690px) 100vw, 690px\" \/><\/figure><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ Swift\u4e2d\u5229\u7528Rest Api\u521b\u5efaUploadId\n   \/\/ \u53c2\u6570\uff1a bearerToken\uff1a\u6b65\u9aa41\u53d6\u5f97\u7684bearerToken   \n   \/\/       bucketName\uff1aIBM Storage\u4e2d\u7684\u5b58\u50a8\u6876\u7684\u540d\u5b57\n   \/\/       fileName\uff1a\u4e0a\u4f20\u7684\u6587\u4ef6\u540d\u5b57\u3002\n   func createUploadId(bearerToken: String, bucketName: String, fileName: String, completion: @escaping ([String: Any]) -> Void) {\n        \/\/ \u7f16\u8f91url\n        guard let url = URL(string: \"https:\/\/s3.au-syd.cloud-object-storage.appdomain.cloud\/\\(bucketName)\/\\(fileName)?uploads\") else { return }\n        var request = URLRequest(url: url)\n\n        \/\/ POST\u65b9\u5f0f\u63d0\u4ea4\n        request.httpMethod = \"POST\"\n        \/\/ Header\u8bbe\u7f6e bearerToken\n        request.addValue(\"bearer \\(bearerToken)\", forHTTPHeaderField: \"Authorization\")\n\n        let urlconfig = URLSessionConfiguration.default\n        urlconfig.timeoutIntervalForRequest = 60\n        urlconfig.timeoutIntervalForResource = 60\n\n        let session = URLSession(configuration: urlconfig, delegate: nil, delegateQueue: OperationQueue.main)\n\n        session.dataTask(with: request) { (data, response, error) in\n            var resultArray: [String: Any] = [:]\n            if let response = response {\n                print(response)\n            }\n            if let data = data, let dataString = String(data: data, encoding: .utf8) {\n                \/\/ \u6ce8\u610f \u8fd4\u56de\u7ed3\u679c\u662fXML\u683c\u5f0f\u7684\uff0c\u8fd9\u91cc\u9762\u6309\u5b57\u7b26\u4e32\u8f93\u51fa\uff0c\u5982\u679c\u8981\u53d6\u5f97\u5404\u4e2a\u8282\u70b9\u7684\u503c\uff0c\u5219\u9700\u8981\u89e3\u6790XML\u3002\n                print(\"Response data string:\\n \\(dataString)\")\n            }\n        }.resume()\n    }<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\u8fd4\u56de\u7ed3\u679c:\n &lt;?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>&lt;InitiateMultipartUploadResult xmlns=\"http:\/\/s3.amazonaws.com\/doc\/2006-03-01\/\">&lt;Bucket>xxxx&lt;\/Bucket>&lt;Key>test555.mp4&lt;\/Key>&lt;UploadId>xxxx-485f-xxxx-bb3c-xxxxx&lt;\/UploadId>&lt;\/InitiateMultipartUploadResult><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">3. \u5728\u5ba2\u6237\u7aef\u9884\u5148\u5206\u5272\u9700\u8981\u4e0a\u4f20\u7684\u6587\u4ef6\u3002<\/h5>\n\n\n\n<p>\u6211\u4eec\u53ef\u4ee5\u5728\u4e0a\u4f20\u524d\u9884\u5148\u5206\u5272\u5927\u6587\u4ef6\uff0c\u628a\u5404\u4e2a\u5757\u6587\u4ef6\u5757\u7269\u7406\u5b58\u50a8\u5728\u8bbe\u5907\u4e0a\u3002\u5f53\u7136\u6211\u4eec\u4e5f\u53ef\u4ee5\u901a\u8fc7\u6307\u9488\u504f\u79fb\u8bfb\u53d6\u6587\u4ef6\u6570\u636e\uff0c\u628a\u8bfb\u53d6\u7684\u503c\u653e\u5165\u5185\u5b58\u4e2d\uff0c\u4e0b\u9762\u7684\u4ee3\u7801\u662f\u771f\u5b9e\u5206\u5272\u6587\u4ef6\u5757\u7684\u4f8b\u5b50\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">  \/\/ \u6587\u4ef6\u5757\u7684\u5927\u5c0f20MB\n  var filePartSize: Int = 20971520\n\n  \/\/ \u53d6\u5f97\u6587\u4ef6\u5757\u8def\u5f84\uff0c\u653e\u5230document\u6587\u4ef6\u5939\u4e0b\u9762\n  let manager = FileManager.default\n  let urlForDocument = manager.urls(for: .documentDirectory, in: .userDomainMask)\n  let videoPartPath = urlForDocument[0]\n\n  \/\/ \u53c2\u6570  videoName\uff1a\u6587\u4ef6\u540d   videoPath\uff1a\u6587\u4ef6\u8def\u5f84  videoSize\uff1a\u6587\u4ef6\u7684Size\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762getFileSize\u65b9\u6cd5\u53d6\u5f97  uploadId\uff1a\u6b65\u9aa42\u53d6\u5f97\u7684uploadId\n  computeFilePartSize(videoName: String, videoPath: String, videoSize: String, uploadId: String) {\n        if Int(videoSize)! &lt;= filePartSize {\n            \n            let filePartData = readFileByPart(videoName: videoName, videoPath: videoPath, videoBeginOffset: \"0\", videoPartSize: videoSize)\n            createFile(name: videoName, fileBaseUrl:videoPartPath!, data: filePartData!)\n            \n        } else {\n            let loop = Int(videoSize)! \/ filePartSize\n            for i in 0..&lt;loop {\n                \n                let filePartData = readFileByPart(videoName: videoName, videoPath: videoPath, videoBeginOffset: \"\\(i * filePartSize)\", videoPartSize: \"\\(filePartSize)\")\n                createFile(name: videoName, fileBaseUrl:videoPartPath!, data: filePartData!)\n            }\n\n            let lastSize = Int(videoSize)! % filePartSize\n            if lastSize > 0 {\n                \n                let filePartData = readFileByPart(videoName: videoName, videoPath: videoPath, videoBeginOffset: \"\\(loop * filePartSize)\", videoPartSize: \"\\(lastSize)\")\n                createFile(name: videoName, fileBaseUrl:videoPartPath!, data: filePartData!)\n            }\n        }\n    }\n\n  \/\/ \u53d6\u5f97\u6587\u4ef6Size\u7684\u65b9\u6cd5\u3002\n  func getFileSize(videoName: String, videoPath: String) -> String {\n        let manager = FileManager.default\n        let attributes = try? manager.attributesOfItem(atPath: videoPath)\n        return \"\\(attributes![FileAttributeKey.size]!)\"\n    }\n\n   func readFileByPart(videoName: String, videoPath: String, videoBeginOffset: String, videoPartSize: String) -> Data? {\n        let readHandle = FileHandle.init(forReadingAtPath: videoPath)\n        \/\/ \u901a\u8fc7\u6307\u9488\u7684\u504f\u79fb\uff0c\u5c40\u90e8\u8bfb\u53d6\u6587\u4ef6\u6570\u636e\u3002\n        readHandle?.seek(toFileOffset: UInt64(videoBeginOffset)!)\n        let data = readHandle?.readData(ofLength: Int(videoPartSize)!)\n        return data!\n    }<\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">4.\u4e0a\u4f20\u5206\u5757\u6587\u4ef6<\/h5>\n\n\n\n<p>\u5411\u5bf9\u8c61\u53d1\u51fa\u4f7f\u7528\u67e5\u8be2\u53c2\u6570&nbsp;<code>partNumber<\/code>&nbsp;\u548c&nbsp;<code>uploadId<\/code>&nbsp;\u7684&nbsp;<code>PUT<\/code>&nbsp;\u8bf7\u6c42\u5c06\u4e0a\u4f20\u5bf9\u8c61\u7684\u4e00\u4e2a\u5206\u5757\u3002\u8fd9\u4e9b\u5206\u5757\u53ef\u4ee5\u6309\u5e8f\u5217\u4e0a\u4f20\uff0c\u4e5f\u53ef\u4ee5\u5e76\u884c\u4e0a\u4f20\uff0c\u4f46\u5fc5\u987b\u6309\u987a\u5e8f\u7f16\u53f7\u3002\u4e0a\u4f20\u6210\u529f\u4ee5\u540e\uff0cHttp Response\u4f1a\u8fd4\u56deEtag\u3002<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-78-1024x479.png\" alt=\"\" class=\"wp-image-3293\" width=\"740\" height=\"345\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78-1024x479.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78-300x140.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78-768x359.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78-1536x719.png 1536w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78-830x388.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78-230x108.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78-350x164.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78-480x225.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-78.png 1594w\" sizes=\"(max-width: 740px) 100vw, 740px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-79-1024x330.png\" alt=\"\" class=\"wp-image-3294\" width=\"712\" height=\"229\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79-1024x330.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79-300x97.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79-768x247.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79-1536x494.png 1536w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79-830x267.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79-230x74.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79-350x113.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79-480x154.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-79.png 1560w\" sizes=\"(max-width: 712px) 100vw, 712px\" \/><\/figure><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> var appDelegateComm: AppDelegate?\n\n\/\/ \u4e0b\u9762\u7684\u4f8b\u5b50\u662fSwift\u4e2d\uff0c\u540e\u53f0\u4e0a\u4f20\u6587\u4ef6\u7684\u4f8b\u5b50\uff0c\u9700\u8981\u7528\u5230urlSession uploadTask\u3002\n \/\/ \u53c2\u6570\uff1a  bearerToken\uff1a\u6b65\u9aa41\u53d6\u5f97\u5230\u7684bearerToken\n \/\/        bucketName\uff1a\u5b58\u50a8\u6876\u7684\u540d\u5b57\n \/\/        fileName\uff1a\u4e0a\u4f20\u7684\u6587\u4ef6\u540d\n \/\/        partNumber\uff1a\u5757\u6587\u4ef6\u7684\u7f16\u53f7\n \/\/        uploadId\uff1a\u6b65\u9aa42\u53d6\u5f97\u7684uploadId\n \/\/        videoPartSize\uff1a\u6587\u4ef6\u5757\u7684Size\n \/\/        fileBaseUrl\uff1a\u5757\u6587\u4ef6\u7684Url\u5730\u5740\n  func upLoadFileBackground(bearerToken: String, bucketName: String, fileName: String, partNumber: String, uploadId: String, videoPartSize: String, name: String, fileBaseUrl: URL) {\n        \/\/ \u7f16\u8f91url\n        guard let url = URL(string: \"https:\/\/s3.au-syd.cloud-object-storage.appdomain.cloud\/\\(bucketName)\/\\(fileName)?partNumber=\\(partNumber)&amp;uploadId=\\(uploadId)\") else { return }\n\n        var request = URLRequest(url: url)\n        \/\/ \u6ce8\u610f\u662fPUT\u63d0\u4ea4\n        request.httpMethod = \"PUT\"\n        \n        \/\/ \u8bbe\u5b9aHTTPHeader\n        request.addValue(\"bearer \\(bearerToken)\", forHTTPHeaderField: \"Authorization\")\n        request.addValue(videoPartSize, forHTTPHeaderField: \"Content-Length\")\n\n        \/\/ \u8bbe\u5b9abackground config\uff0cdelegate\n        let config = URLSessionConfiguration.background(withIdentifier: (\"\\(Date().timeIntervalSince1970)_\\(partNumber)\"))\n        \/\/ \u91cd\u8981\u628a appDelegateComm\u5bf9\u8c61\u4f5c\u4e3a\u4ee3\u7406\u5bf9\u8c61 \u8d4b\u503c\u7ed9config\n        let session = URLSession(configuration: config, delegate: appDelegateComm, delegateQueue: OperationQueue.main)\n        \n        let fileUrl = fileBaseUrl.appendingPathComponent(name)\n\n        \/\/ \u8fd9\u91cc\u9700\u8981\u6ce8\u610f\uff0c\u5fc5\u987b\u7528\u3010session.uploadTask(with: request, fromFile: fileUrl)\u3011  \u53c2\u6570\u662ffromFile\uff0c\u624d\u80fd\u540e\u53f0\u8fd0\u884c\u3002\n        let uploadTask = session.uploadTask(with: request, fromFile: fileUrl)\n        uploadTask.resume()\n\n    }\n\n\/\/ \u91cd\u8981 AppDelegate\u5b9e\u73b0URLSessionDataDelegate \u548c URLSessionDelegate\u4ee3\u7406\u534f\u8bae\nclass AppDelegate: UIResponder, UIApplicationDelegate, URLSessionDelegate, URLSessionDataDelegate {\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        \/\/ Override point for customization after application launch.\n\n        let manager = FileManager.default\n        let urlForDocument = manager.urls(for: .documentDirectory, in: .userDomainMask)\n        videoPartPath = urlForDocument[0]\n    \n        session.delegate = self\n        \/\/ \u8fd9\u91cc\u9762\u628a AppDelegate\u5bf9\u8c61 \u8d4b\u503c\u7ed9 appDelegateComm\n        appDelegateComm = self\n\n        return true\n    }\n\n    \/\/ \u91cd\u8981 \u5f53uploadTask\u5b8c\u6210\u65f6\uff0c\u4f1a\u8c03\u7528\u4e0b\u9762\u7684\u65b9\u6cd5\n    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {\n        if let httpResponse = dataTask.response as? HTTPURLResponse {\n            print(httpResponse)\n            \/\/ \u4eceresponse\u91cc\u9762\u53ef\u4ee5\u62ff\u5230\u8fd4\u56de\u503c\n            let etag = httpResponse.allHeaderFields[\"Etag\"] as? String\n            print(etag)\n       }\n    }\n\n    func urlSession(_ session: URLSession, task: URLSessionTask,\n        didCompleteWithError error: Error?) {\n        upLpadProcess.removeValue(forKey: session.partInfoId)\n    }\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\u8fd4\u56de\u7ed3\u679c\uff1a\n&lt;NSHTTPURLResponse: 0x600002e69b20> { URL: https:\/\/s3.au-syd.cloud-object-storage.appdomain.cloud\/xxx\/test.mp4?partNumber=6&amp;uploadId=0100017a-4891-6d23-60fa-6b0ba4869729 } { Status Code: 200, Headers {\n    \"Content-Length\" =     (\n        0\n    );\n    Date =     (\n        \"Thu, 01 Jan 1970 00:00:00 GMT\"\n    );\n    Etag =     (\n        \"\\\"xxx1e935b62e52c97906011682\\\"\"\n    );\n    Server =     (\n        Cleversafe\n    );\n    \"X-Clv-Request-Id\" =     (\n        \"b5f4adaa-a7eb-4de7-9e16-42c6fe891a74\"\n    );\n    \"X-Clv-S3-Version\" =     (\n        \"2.5\"\n    );\n    \"x-amz-request-id\" =     (\n        \"b5f4adaa-a7eb-4de7-9e16-42c6fe891a74\"\n    );\n} }<\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">5.\u5b8c\u6210\u5206\u5757\u4e0a\u4f20<\/h5>\n\n\n\n<p>\u5411\u5bf9\u8c61\u53d1\u51fa\u4f7f\u7528\u67e5\u8be2\u53c2\u6570&nbsp;<code>uploadId<\/code>&nbsp;\u5e76\u4e14\u4e3b\u4f53\u4e2d\u5305\u542b\u76f8\u5e94 XML \u5757\u7684&nbsp;<code>PUT<\/code>&nbsp;\u8bf7\u6c42\u5c06\u5b8c\u6210\u5206\u5757\u4e0a\u4f20\u3002<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-80-1024x698.png\" alt=\"\" class=\"wp-image-3304\" width=\"713\" height=\"485\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80-1024x698.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80-300x204.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80-768x523.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80-1536x1047.png 1536w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80-830x566.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80-230x157.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80-350x239.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80-480x327.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-80.png 1570w\" sizes=\"(max-width: 713px) 100vw, 713px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2021\/06\/image-81-1024x584.png\" alt=\"\" class=\"wp-image-3305\" width=\"702\" height=\"400\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81-1024x584.png 1024w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81-300x171.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81-768x438.png 768w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81-1536x876.png 1536w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81-830x473.png 830w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81-230x131.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81-350x200.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81-480x274.png 480w, https:\/\/92it.top\/wp-content\/uploads\/2021\/06\/image-81.png 1582w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/figure><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> \/\/ \u7f16\u8f91\u597dConfig\u7684\u5b57\u7b26\u4e32\nvar configStr = \"&lt;CompleteMultipartUpload>&lt;Part>&lt;PartNumber>1&lt;\/PartNumber>&lt;ETag>\"7417ca8d45a71b692168f0419c17fe2f\"&lt;\/ETag>&lt;\/Part>&lt;Part>&lt;PartNumber>2&lt;\/PartNumber>&lt;ETag>\"7417ca8d45a71b692168f0419c17fe2f\"&lt;\/ETag>&lt;\/Part>&lt;\/CompleteMultipartUpload>\"\n\nfunc completeUpload(bearerToken: String, bucketName: String, fileName: String, uploadId: String, configStr: String, completion: @escaping ([String: Any]) -> Void) {\n        guard let url = URL(string: \"https:\/\/s3.au-syd.cloud-object-storage.appdomain.cloud\/\\(bucketName)\/\\(fileName)?uploadId=\\(uploadId)\") else { return }\n\n        var request = URLRequest(url: url)\n        request.httpMethod = \"POST\"\n        request.addValue(\"bearer \\(bearerToken)\", forHTTPHeaderField: \"Authorization\")\n        request.addValue(\"text\/plain; charset=utf-8\", forHTTPHeaderField: \"Content-Type\")\n\n        let urlconfig = URLSessionConfiguration.default\n        urlconfig.timeoutIntervalForRequest = 60\n        urlconfig.timeoutIntervalForResource = 60\n\n        \/\/ \u7f16\u8f91\u597d\u7684configStr\u5b57\u7b26\u4e32\u3002\n        let data: Data = configStr.data(using: .utf8)!\n        request.httpBody = data\n\n        let session = URLSession(configuration: urlconfig, delegate: nil, delegateQueue: OperationQueue.main)\n\n        session.dataTask(with: request) { (data, response, error) in\n\n            var resultArray: [String: Any] = [:]\n\n            if let httpResponse = response as? HTTPURLResponse {\n\n                if httpResponse.statusCode == 200 {\n                    resultArray.updateValue(\"ok\", forKey: \"status\")\n                    DispatchQueue.main.async {\n                        completion(resultArray)\n                    }\n                } else {\n                    resultArray.updateValue(\"error\", forKey: \"status\")\n                    DispatchQueue.main.async {\n                        completion(resultArray)\n                    }\n                }\n            }\n        }.resume()\n    }<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>IBM Storage \u5b58\u50a8\u5927\u5bf9\u8c61\u5206\u5757\u4e0a\u4f20\uff0c\u539f\u7406\u6bd4\u8f83\u7b80\u5355\uff0c\u5c31\u662f\u5728\u5ba2\u6237\u7aef\u628a\u9700\u8981\u4e0a\u4f20\u7684\u5927\u6587\u4ef6\u5206\u5272\u6210\u5757\uff0c\u7136\u540e\u5e76\u884c\u4e0a\u4f20 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,6],"tags":[],"_links":{"self":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/3258"}],"collection":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3258"}],"version-history":[{"count":42,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/3258\/revisions"}],"predecessor-version":[{"id":3312,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/3258\/revisions\/3312"}],"wp:attachment":[{"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}