-
内存缓存/运行时缓存分为两部分:活动缓存(ActiveResource)和Lru内存缓存(LruResourceCache)。缓存机制简介1、缓存的图片资源原始图片(Source) :即图片源的图片初始大小和分辨率;转换后的图片(Result) :经过尺寸缩放和大小压缩等处理后的图片;当使用Glide加载图片时,Glide会默认根据View视图对图片进行压缩和转换,而不显示原始图。(这也是Glide加载速度高于Picasso的原因)2、缓存机制设计Glide的缓存功能设计成二级缓存:内存缓存和硬盘缓存。(从网络加载不属于缓存)内存缓存:防止重复将图片读入到内存,造成内存资源浪费,只缓存转换后的图片,而不是原始图片;磁盘缓存:防止重复从网络或其他地方下载和读取数据,可缓存原始图片和转换过后的图片,用户自行设置;在Glide中,缓存的读取顺序为:内存缓存 –> 磁盘缓存 –> 网络 ,内存缓存和磁盘缓存相互不影响,独立配置,内存缓存是默认开启的。Glide的缓存机制使得Glide具备非常好的图片缓存效果,从而使得具备较高的图片加载效率。以下是Glide的相关代码:// 默认开启内存缓存,用户不需要作任何设置Glide.with(this).load(url).into(imageView);// 可通过API禁用内存缓存功能Glide.with(this).load(url).skipMemoryCache(true) // 禁用内存缓存 .into(imageView);Glide.with(this).load(url) .diskCacheStrategy(DiskCacheStrategy.NONE) // 不缓存任何图片,即禁用磁盘缓存 .into(imageView);// DiskCacheStrategy.NONE:不缓存任何图片,即禁用磁盘缓存// DiskCacheStrategy.ALL :缓存原始图片 & 转换后的图片// DiskCacheStrategy.SOURCE:只缓存原始图片(原来的全分辨率的图像,即不缓存转换后的图片)// DiskCacheStrategy.RESULT:(默认)只缓存转换后的图片(即最终的图像:降低分辨率后 / 或者转换后 ,不缓存原始图片3、 缓存类型活动缓存(ActiveResource):存储正在使用的图片;Lru内存缓存(LruResourceCache):图片解析完成后并最近被加载过会放到内存中;磁盘缓存-资源类型(DiskCache - Resource):被解码后的图片写入磁盘文件中;磁盘缓存-原始数据(DiskCache - Data):网络请求成功或在本地获取成功后,将原始数据在磁盘中缓存;Lru(Least Recently Used):最近最少使用,它的核心思想是,当缓存满的时候,会优先淘汰最近最少使用的缓存对象。4、内存缓存/运行时缓存内存缓存/运行时缓存分为两部分:活动缓存(ActiveResource)和Lru内存缓存(LruResourceCache)。LinkedHashMap继承自HashMap,在此基础上增加了双向链表的结构,每次访问数据的时候,会更新被访问的数据的链表指针。比如说从链表中删除并不是真正的删除数据,只是移动了链表的指针。Lru内存缓存:使用LinkedHashMap来缓存资源(强引用),并设定一个缓存的大小。如果有资源被访问到,首先会在链表中删除该节点,然后再添加到链表头,这样就可以保证链表头部的节点是最近访问过的。而当缓存的数量达最大值的时候,就会将链表尾部(最近最少使用)的数据移除。但是这样做有一个风险,就是容易将正在使用的资源回收掉。Glide这样设计:从内存缓存(LruResourceCache)中拿到资源时候就主动添加到活动缓存(ActiveResource)中,并清理Lru内存缓存(LruResourceCache)中的资源,这样做的好处就是是保护正在使用资源不被Lru算法回收掉。ActiveResources是一个弱引用的HashMap,用来缓存正在使用的图片,保存这个图片不会被Lru算法回收掉。图片用完之后会重新添加到Lru内存缓存中。ActiveResources和LruResourceCache是内存缓存,属于运行时缓存且互斥(同一张图片不会同时缓存在ActiveResources和LruResourceCache中),应用被杀死后内存缓存将不存在。5、 磁盘缓存磁盘缓存策略:DiskCacheStrategy.NONE:表示不缓存任何内容;DiskCacheStrategy.RESOURCE:在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源;DiskCacheStrategy.DATA:在资源解码前将原始数据写入磁盘缓存;DiskCacheStrategy.ALL :使用DATA和RESOURCE缓存数据;DiskCacheStrategy.AUTOMATIC:它会尝试对本地和远程图片使用最佳的策略。当加载远程数据时,AUTOMATIC 策略仅会存储未被加载过程修改过的原始数据,因为下载远程数据相比调整磁盘上已经存在的数据要昂贵得多。对于本地数据,AUTOMATIC 策略则会仅存储变换过的缩略图,因为即使需要再次生成另一个尺寸或类型的图片,取回原始数据也很容易。默认使用这种缓存策略;在使用Glide去加载一张图片的时候,Glide默认不会将原始图片展示出来,而是会对图片进行压缩和转换。我们既可以缓存转换过的图片,也可以缓存转换之前的原始图片。采用LRU算法的缓存有两种:LruCache和DisLruCache,分别用于实现内粗缓存和硬盘缓存原文链接:https://www.51cto.com/article/747365.html
-
正是由于在RPC数据包中包含的这些关键信息,当主机端发送的消息被服务端接收后,服务端根据这些信息就能知道应该调用哪个存根函数。前文我们介绍了NFS的整体架构,其核心是将主机端的函数调用通过网络传输到服务端,并转化为服务端的函数调用。其主要实现是主机端与服务端的一一对应的存根。那么这种转化是如何进行的呢?这就涉及到RPC协议了。在Linux NFS中,将网络文件系统分为两层,其中RPC协议承载了NFS协议。由于RPC协议的存在,是的NFS协议变得非常简单。RPC协议的全称为Remote Procedure Call,翻译成中文是远程过程调用。也就是通过该协议,可以实现一个远程的函数调用,这样在客户端调用一个函数,可以在服务端完成业务处理。而对于客户端来说并不关心该函数是在客户端还是服务端。这里的函数是经过特殊方式实现的,在NFS中称为存根(stub)。以Linux内核中的实现为例,文件系统的所有操作都对应着一个存根函数,具体如下所示。而客户端的这些存根函数在服务端也是有一一对应的存根函数的。Linux NFS中服务端的存根函数如下所示。所以,当客户端文件系统希望完成某一个文件操作时,比如创建子目录。那么在文件系统层面可以直接调用客户端的存根函数,比如nfs3_proc_mkdir。而该函数会将请求封装后通过RPC发送到服务端,服务端的程序会根据解析后的消息调用服务端对应的存根函数完成客户端期望的操作,然后给客户端反馈。那么这个流程是如何实现的呢?这就涉及到RPC协议的内容了。RPC的原理其实非常简单,如下是RPC数据包的格式,可以看出该格式中包含很多字段。这些字段就是用来描述存根函数的。Sun的RPC协议在设计的时候期望实现对多种服务的支持,比如NFS协议、挂载协议和NLM等。因此在设计RPC协议的时候,RPC有3个相关的字段来进行标识,其中Program字段标识程序,区分NFS、MOUNT和NLM等其它程序类型;Program Version字段标识程序版本,考虑升级的兼容性;Procedure字段则标识程序中的过程(函数),也就是存根函数。通过上述Program和Procedure等关键信息,当服务端收到该消息时就可以知道应该由哪个版本的哪个程序来处理该消息,而且进一步知道应该调用哪个存根函数(函数指针)来进行处理。上面的介绍更多的是理论层面的,我们通过WireShark抓个包看看Sun RPC是如何传输数据的,以及数据的格式。如图5‑8所示是我们抓取的挂载命令的数据包,我们可以对比一下该数据包的内容与协议的关系。可以看到,这里Program是100005;Program版本是3,也就是NFS v3的数据;Procedure的值为1。由于WireShark是支持RPC和NFS协议的,因此在图5‑8中上半部分可以看到具体的描述信息。在该图的下半部分则是原始的数据包数据。正是由于在RPC数据包中包含的这些关键信息,当主机端发送的消息被服务端接收后,服务端根据这些信息就能知道应该调用哪个存根函数。原文链接 https://www.51cto.com/article/762669.html
-
@try { if (self.currentTask != nil) { [self.currentTask cancel]; } self.config = config; NSString * endPoint = [self.config objectForKey:@"endPoint"]; NSString * AK = [self.config objectForKey:@"accessKey"]; NSString * SK = [self.config objectForKey:@"secretKey"]; NSString * ST = [self.config objectForKey:@"securityToken"]; NSString * objectKey = [self.config objectForKey:@"objectKey"]; NSString * bucket = [self.config objectForKey:@"bucket"]; // 初始化身份验证 OBSStaticCredentialProvider *credentialProvider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:AK secretKey:SK]; // OBSSTSCredentialProvider *credentialProvider = [[OBSSTSCredentialProvider alloc] initWithAccessKey:AK secretKey:SK]; credentialProvider.securityToken = ST; //初始化服务配置 OBSServiceConfiguration *conf = [[OBSServiceConfiguration alloc] initWithURLString:[NSString stringWithFormat:@"https://%@",endPoint] credentialProvider:credentialProvider]; // 初始化client OBSClient * client = [[OBSClient alloc] initWithConfiguration:conf]; _obsClient = client; #if DEBUG // *****日志设置******* // 设置系统日志打印 [client addLogger:[OBSDDASLLogger sharedInstance]]; // 打开窗口打印 [client addLogger:[OBSDDTTYLogger sharedInstance]]; // 设置日志文件记录 OBSDDFileLogger *fileLogger = [[OBSDDFileLogger alloc] init]; // 保留时间 fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling // 最大文件数目 fileLogger.logFileManager.maximumNumberOfLogFiles = 7; // 自定义日志添加 [client addLogger:fileLogger]; // 日志文件地址 OBSDDLogFileInfo *ts =[fileLogger currentLogFileInfo]; NSLog(@"%@", ts); // 设置日志等级 [client setLogLevel:OBSDDLogLevelDebug]; // 开启日志 [client setASLogOn];#endif // 分段上传的最大并发数 client.configuration.maxConcurrentUploadRequestCount = 3; // 分段上传请求的最大连接数 client.configuration.uploadSessionConfiguration.HTTPMaximumConnectionsPerHost = 5; filePath = [filePath stringByReplacingOccurrencesOfString:@"file://" withString:@""]; // 填写Bucket名称,例如examplebucket。 // 填写文件完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。 NSString * contentMd5 = [self.class base64Md5ForFilePath:filePath]; if (contentMd5 == nil) { @throw [NSException exceptionWithName:OBSBFTaskErrorDomain reason:@"not found file" userInfo:nil]; } // 获取对象属性 OBSGetObjectMetaDataRequest *metaDataRequest = [[OBSGetObjectMetaDataRequest alloc] initWithBucketName:bucket objectKey:objectKey]; __block BOOL hasUpload = NO; OBSBFTask *metaDataTask = [client getObjectMetaData:metaDataRequest completionHandler:^(OBSGetObjectMetaDataResponse *response, NSError *error){ NSLog(@"meta:%@\n storageClass:%@\n websiteRedirectlocation:%@\n size:%@", response.metaDataDict, @(response.storageClass), response.websiteRedirectLocation, response.size); NSString * md5 = [response.metaDataDict valueForKey:@"contentmd5"]; if (md5 == nil) { md5 = [response.metaDataDict valueForKey:@"contentMd5"]; } if (md5 != nil && [md5 isEqualToString:contentMd5]) { [self sendEventWithName:@"obsUploadProgress" body:@{ @"type" : @"onProgress", @"currentSize" : [NSString stringWithFormat:@"%@", response.size], @"totalSize" : [NSString stringWithFormat:@"%@", response.size], @"md5" : contentMd5, @"objectKey" : objectKey, @"transferPercentage" : @"100" }]; hasUpload = YES; return; } }]; [metaDataTask waitUntilFinished]; if (hasUpload) { if (resolve) { resolve(@{ @"filePath" : filePath, @"md5" : contentMd5, @"objectKey" : objectKey }); } NSLog(@"文件已经存在,无需上传,直接成功 ! %@, %@", objectKey, filePath); return; } OBSUploadFileRequest *request = [[OBSUploadFileRequest alloc]initWithBucketName:bucket objectKey:objectKey uploadFilePath:filePath]; // 分段大小为5MB request.partSize = [NSNumber numberWithInteger: 5 * 1024*1024]; // // 开启断点续传模式 request.enableCheckpoint = YES; // // 指定checkpoint文件路径 request.checkpointFilePath = [filePath stringByAppendingString:@".obsuploadcheckpoint.txt"]; request.enableMD5Check = YES;// if ([[NSFileManager defaultManager] fileExistsAtPath:request.checkpointFilePath]) {// //获取JSON文件的路径// //将JSON文件转换成NSData对象// NSData *data = [[NSData alloc] initWithContentsOfFile:request.checkpointFilePath];// //将NSData对象转换成JSON对象// NSError *error = nil;// NSDictionary* jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];// //检查转换是否成功// if (error != nil) {// NSLog(@"解析JSON失败:%@",error);// } else {// //解析JSON成功// NSString * requestID = [jsonObject valueForKey:@"requestID"];// NSString * uploadID = [jsonObject valueForKey:@"uploadID"];//// NSString * uploadFilePath = [jsonObject valueForKey:@"uploadFilePath"];// request.requestID = requestID;//// request.lastUploadFilePath = uploadFilePath;// NSLog(@"checkpoint requestID:%@,uploadID:%@",requestID, uploadID);//// self.upload2(jsonObject);// }// } NSMutableDictionary * metaDataDict = [NSMutableDictionary dictionaryWithDictionary:request.metaDataDict]; [metaDataDict setObject:contentMd5 forKey:@"contentMd5"];// [metaDataDict setObject:@{ @"md5": contentMd5 } forKey:@"userMetadata"]; [request setMetaDataDict:metaDataDict]; // 上传文件 request.uploadProgressBlock = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { if (totalBytesExpectedToSend < 1) { return; } NSLog(@"%0.1f%%",(float)floor(totalBytesSent*10000/totalBytesExpectedToSend)/100); NSLog(@"%lld, %lld, %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend); if (!self.hasListeners) { return; } [self sendEventWithName:@"obsUploadProgress" body:@{ @"type" : @"onProgress", @"currentSize" : [NSString stringWithFormat:@"%lld", totalBytesSent], @"totalSize" : [NSString stringWithFormat:@"%lld", totalBytesExpectedToSend], @"md5" : contentMd5, @"objectKey" : objectKey, @"transferPercentage" : [NSString stringWithFormat: @"%0.0f",(float)floor(totalBytesSent*10000/totalBytesExpectedToSend)/100] }]; }; self.currentTask = request; OBSBFTask *task = [client uploadFile:request completionHandler:^(OBSUploadFileResponse *response, NSError *error) { NSLog(@"%@",response); self.currentTask = nil; if(error){ // 打印错误信息 NSLog(@"文件上传失败"); NSLog(@"%@",error); if (reject) { reject(@"-1", @"上传失败", error); } return; } // 上传文件成功,返回200,打印返回响应值 if([response.statusCode isEqualToString:@"200"]){ NSLog(@"文件上传成功"); NSLog(@"%@",response); NSLog(@"%@",response.etag); if (resolve) { resolve(@{ @"filePath" : filePath, @"md5" : contentMd5, @"objectKey" : objectKey }); } NSLog(@"upload object success! %@, %@", objectKey, filePath); } else { NSLog(@"文件上传失败"); if (reject) { reject(@"-1", @"上传失败", nil); } } }]; [task waitUntilFinished];} @catch(NSException *e) { self.currentTask = nil; NSLog(@"obs upload error: %@", e); NSError *error = [NSError errorWithDomain:OBSBFTaskErrorDomain code:kOBSBFMultipleErrorsError userInfo:@{ @"errors": e }]; reject(@"-1", e.reason, error);}
-
browserjs 看官方文档生成临时url访问, AK/SK也是硬编码,这还是会有安全问题,如何解决啊
-
import ObsClient from "../../node_modules/esdk-obs-browserjs/dist/esdk-obs-browserjs-without-polyfill.3.23.5.min.js"; 这样子也不可以 let obsClient = new ObsClient({ access_key_id: this.obsObj.access_key_id, secret_access_key: this.obsObj.secret_access_key, server: this.obsObj.server });
-
1、使用附件 index 文件在FunctionGraph服务中创建函数(创建时需要把rar压缩包转为zip压缩包),创建函数请参考 cid:link_0 ;2、修改requirements.txt文件的内容,把里面的内容替换成需要打包的依赖,多个依赖换行隔开;3、在index.py文件内,参考注释内容修改红框内的代码。部署执行代码后,会自动把requirements.txt内的所有依赖打包成一个文件并保存到OBS桶内,保存的文件名和桶的地址由index.py文件中红框内代码决定
-
第一次1000个删除成功了990个,重试时依旧传递1000个key,重试时会因为已删除的990个导致本次删除失败吗?
-
您好,我在使用OBS javasdk的文件上传API,使用中,我发现,对于大文件,使用官方提供的并发上传文件示例,比直接调 putObject方法速度还慢,具体代码如下:1.并发分段上传代码官方示例https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0607.html2.调用 putObject 上传文件public SaveObjectResult saveObject(String bucket, String objectKey, MultipartFile file) throws Exception { // 校验桶名称是否正确 bucket = checkBucketName(bucket); InputStream in = file.getInputStream(); SaveObjectResult saveObjectResult = new SaveObjectResult(); saveObjectResult.setOk(Boolean.FALSE); saveObjectResult.setStorageMediaType(OSSTypeEnum.OBS.name()); PutObjectResult putObjectResult = getClient().putObject(bucket, objectKey, in); if (putObjectResult != null && putObjectResult.getStatusCode() == HttpStatus.HTTP_OK) { saveObjectResult.setOk(Boolean.TRUE); saveObjectResult.setAccessUrl(putObjectResult.getObjectUrl()); } return saveObjectResult; }此处直接使用ObsCLient 的 PutObjectResult putObject(String bucketName, String objectKey, InputStream input) 方法。测试结果发现,使用并发分段上传,并没有节省时间,反而比直接使用putObject还慢,为什么会这样?怎么优化,才能让上传更快?
-
10岁学Python,12岁学C++在数十场科技创新大赛中拔得头筹为解决一个技术难题独自一人从大连飞往东莞HDC.Cloud2023现场与华为云扫地僧面对面交流这就是少年开发者苏家祺壮志凌云,未来可期video一个中学生的暑期特别之旅故事要从一个技术bug说起。在这个炎热的暑假,刚初三毕业的苏家祺,因为一个开源软件的内核时间同步问题,苦恼不已,在一次又一次的失败尝试之后,技术交流群的一则消息引起了他的注意:那是来自华为云开发者联盟公众号的一篇推文,里面提到华为云即将举办开发者大会,现场将有扫地僧见面会特别活动。作为华为产品的资深使用者,能够与技术大佬面对面切磋技术令苏家祺心驰神往,于是他果断购买了HDC.Cloud 2023门票,一个人从大连乘坐飞机前往离家2000公里之外的东莞,深度参加了为期三天的华为开发者大会(Cloud)。如今回忆起7月中旬的HDC.Cloud 2023之旅,苏家祺仍有些意犹未尽,“既学到了前沿的AI、大模型、云上运维等技术,也结识了很多技术牛人,收获满满,下次还来。”15岁资深开发者和他的硬核工作室虽然今年才15岁,但苏家祺已经是个有着5年编程经验的“资深”开发者。五年级的时候,在一次学校组织的科教中心科普活动中,苏家祺被塞了一张Python的传单,自此踏上了漫漫编程路。在边折腾边学习的过程中,苏家祺逐渐沉迷于钻研各种技术,从无线电、PCB电路设计、网络运维到3D打印,样样精通的他拿下了数十场科技创新大赛的大奖, 在各种青少年赛事中崭露头角,可谓是英雄出少年。为了更好地研究这些技术,苏家祺把家里的一个小卧室打造成了自己的“工作室”,一眼望过去,各种设备器件令人目不暇接。“这是一个古董的指针式万用表,这是我平常用来听广播的无线电,这是一台3D打印机,这是我的焊台,升温速度非常快…”苏家祺兴致勃勃地介绍起他的这些宝贝,并随手拿起电焊工具,对着桌上的一块电路板DIY起来。工作室最显眼的一处便是一块悬在空中的中控屏,不断跳动变换着的曲线显示着华为云OBS的使用情况, 包括存储的应用量、速率、流量等等。通过这块屏幕,苏家祺可以实时监控了解自己在华为云上搭建的网站运行情况,做个了若指掌的运维人。除了这块小天地,苏家祺还使用华为猫棒、路由器、交换机等设备,在客厅里搭建了简易机房,并通过一根光纤直通工作室,满足日常的软硬件开发网络需求。每每聊起自己辛苦淘来的这些设备,苏家祺便会滔滔不绝、如数家珍,他举着手中的树莓派,说道,“上次用它搭了一个智能家居系统,可惜在运行开源homeassistant时一直报错,研究了很久也没有解决,正好看到HDC上有机会和华为云扫地僧面对面交流,所以火速买好票到现场找技术大佬们解惑答疑。”与华为云专家的“忘年之交”在HDC.Cloud 2023的现场,苏家祺如愿参加了华为云扫地僧见面会,并在专家的指导下解决了困扰他良久的那个技术难题。“华为云的专家都非常专业和热情, 我还给他们看了家里的机房照片,专家很快给了专业指导建议。后来我又尝试将WordPress部署到华为云函数服务上,过程中遇到不少问题,专家有问必答。”苏家祺现在还常常在微信上和华为云专家讨论一些技术问题,两个技术爱好者一见如故,完全没有年龄的隔阂。最近,苏家祺正使用华为云CDN服务和免费的SLL证书搭建个人网站的首页, 华为云专家在帮助他解决网站域名备案的问题。同时,他也在将自己项目的代码托管到CodeArts,通过CodeArts IDE实现随时随地编码,并在云上完成代码检查的工作。在苏家祺看来,相比较其他云厂商,“华为云的一些产品有着别人无我有的创新之处,而且技术支持非常给力,使用体验很棒。”少年开发者的星辰大海从学编程参加比赛,到购买各种器件设备,苏家祺的爸妈一直都很支持他的研究,有时候他也会在网上帮别人制作网站,为自己的小工作室获取一些储备资金。研究这些技术对苏家祺来说,更是繁忙学业之于难得的解压和放松,“通过查资料、学新技术、动手实操、和技术好友交流解决各种难题bug,是特别让人享受的过程,充满成就感。”“用技术改变世界”是每个技术人心中的远大理想,苏家祺也不例外。在HDC.Cloud 2023的专题论坛上,一个关于运维的故事让苏家祺印象深刻。在爆炸式增长的云时代,临场救火式的维护已经远远不够,华为云提出了确定性运维的理念,运维工程师不仅要做“救火队”,更要成为“云上建筑的架构师”,在高度不确定性的环境中保证结果的确定性。这个故事更加坚定了苏家祺做运维的决心,未来他也希望成为一个优秀的云上建筑师,用技术创新让这个数字世界更美好。心怀梦想的少年开发者,正在用他的好奇心和对技术的热爱点燃创新的火焰,未来可期。
-
各位大佬,为什么我用标准示例请求,结果返回 HTTP Code: 404;
-
你好,想咨询下我们之前用其它云厂商的对象存储的时候可以配置一个回调的地址,这个在华为这边有吗?就是视频上传后,会给我们配置好的地址发送一个json消息。
-
1. 华为云对象存储服务,为啥不能用相对路径问题链接:cid:link_0 问题描述:华为云对象存储服务,为啥不能用相对路径 版主解答:使用绝对路径是有原因的,因为python可以在任何目录下启动,他的相对目录是当前执行命令的目录而非文件所在的目录。因此用相对路径的话,可能会产生歧义2. 对象存储与SAN存储和NAS存储相比有什么优势问题链接:cid:link_1 问题描述:对象存储与SAN存储和NAS存储相比较有什么优势? 版主解答: 1.SAN存储提供给应用的是一个LUN或者是一个卷,LUN和卷是面向磁盘空间的一种组织方式,上层应用要通过FC或者ISCSI协议访问SAN。SAN存储处理的是管理磁盘的问题,其他事情都要依靠上层的应用程序实现。 2.NAS存储提供给应用的是一个文件系统或者是一个文件夹,上层应用通过NFS和CIFS协议进行访问。文件系统要维护一个目录树。 3.对象存储更加适合web类应用,基于URL访问地址提供一个海量的桶存储空间,能够存储各种类型的文件对象,对象存储是一个扁平架构,无需维护复杂的文件目录。无需考虑存储空间的限制,一个桶支持近乎无限大的存储空间。3. 下载过程中出现ssl:timeout后,无法再继续下载问题链接:cid:link_2 问题描述:我在C语言中实现了一个通用的下载方法,下载华为云obs文件时,中途出现ssl:timeout,继续进行下载,仍然是ssl:timeout,更换其他的OBS文件也一样。但是此时下载其他文件(非OBS文件)则正常。必须刷新网络后才能正常下载。 版主解答:检查下域名和网址是否一致,如有相同域名多站点则换成多域名ssl证书4. IOS 文件上传后OBSPutObjectResponse 类没有返回objectUrl和objectKey,但是Android的PutObjectResult对象里面有objectUrl和objectKey字段问题链接:cid:link_3 问题描述:IOS 文件上传后OBSPutObjectResponse 类没有返回objectUrl和objectKey,但是Android的PutObjectResult对象里面有objectUrl和objectKey字段,IOS该如何获取对应的字段呢? 版主解答:对于 iOS 端的文件上传后,OBSPutObjectResponse 类确实没有提供 objectUrl 和 objectKey 字段的返回。这可能是由于在 iOS 开发中,广义的云存储服务(OBS)可能不是常用的存储解决方案。 在 iOS 开发中,如果你使用的是云存储服务提供商的 iOS SDK,可能会有不同的返回对象和字段。你可以查阅相关的文档以了解具体的返回数据结构和字段的含义。 如果你在 iOS 中使用的是 OBS 的开源 SDK 或者其他第三方库进行对象上传,你可以进一步检查相关的文档和源代码,以确定返回的具体字段和数据结构。 总之,在不同的平台和开发语言中,不同的 SDK 或库可能会提供不同的返回对象和字段。请确保参考文档或相关资源以获得所需的返回信息。5. 如何选择存储服务问题链接:cid:link_4 问题描述:如果只是备份一些数据,如 10TB 的数据量,存储5年。基本不访问,就是找个地方上传保存备份着。应该选择哪种最划算? 版主解答:OBS存储,然后归档,最便宜。你可以看下区域,每个区域同样配置价格都不一样6. 使用OBS BrowserJS SDK分段上传视频 部分手机报错【暂未解决】问题链接:cid:link_57. OBS的对象存储查询问题问题链接:cid:link_6 问题描述:OBS对象存储里面不是有查询所有对象吗?可是所有对象都是文件夹的路径加文件。有没有提供树形结构的 api 接口?比如桶名为zhtj,那返回的数据就是{"zhtj":{"folder_child":[{"a目录":{"folder_child":[],"file_info":[]}}],"file_info":[]}}这种树结构形式?因为我这边需要做一个和OBS对象存储结构一模一样的前端展示页面。 版主解答:在 OBS(对象存储服务)中,默认情况下,它提供了一种扁平的存储结构,没有直接支持树形结构的 API 接口。每个对象都可以通过其路径进行访问,路径通常是由桶名和文件夹路径组成。 如果您需要在前端展示页面上实现树形结构的效果来显示 OBS 对象存储的内容,您可能需要进行一些额外的工作: 1.获取所有对象:使用 OBS 的 List Objects API 或相关 SDK,您可以获取到桶中的所有对象和文件夹。这些数据通常以列表的形式返回。 2.构建树形结构:在前端展示页面上,您可以使用获取到的对象列表数据来构建树形结构。可以通过解析每个对象的路径,将其转换为树形结构的形式。您可以使用 JavaScript 中的对象、数组等数据结构来表示树形结构,并根据对象的属性关系来组织数据。 3.渲染展示页面:根据构建好的树形结构数据,您可以使用前端框架(如 Vue.js、React 等)或纯 JavaScript 来渲染展示页面,并将树形结构的数据呈现出来。
-
产品要实现多个文件同时断点续传,上传过程中要实时显示对应文件的上传进度。前端使用browserjs实现,obsClient.uploadFile 在ProgressCallback回调里只能获取文件的【已上传的字节数】、【总字节数】、【已使用的时间】三个字段,无法区分是哪个文件的回调,导致无法知道在ProgressCallback方法里,对应的参数【已上传的字节数】是属于哪个文件的。本来是想通过【总字节数】来区分的,但是如果是上传的文件里有两个一样大小的文件就会显示有问题。求大神指教
-
报错信息如下:HEAD https://qian.qian.obs.cn-east-3.myhuaweicloud.com/?apiversion net::ERR_CERT_COMMON_NAME_INVALID
-
自己尝试了几天了,都还是不行,万般无奈之下只能求助各位大神啦 小弟在此先谢谢了
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第三期2026/08/21 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;念擎-华为云AI开发者运营案例开发专家
本期直播内容:AI六层能力首次详细解读 + 新一代华为云开发者空间亮相 + 校园案例直播带练
回顾中
热门标签