• [技术干货] OBS JAVA SDK Demo:设置桶策略
    1      背景介绍OBS桶策略可以给特定用户设置特定的权限。下面代码展示通过JAVA SDK给用户桶设置高级桶策略。2      代码展示需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。前提条件:已创建OBS桶,例如my-bucket123设置的桶策略为:给用户userB给予桶的所有权限和桶内所有对象的读权限桶策略格式如下,其中domain和user请根据实际账号ID和用户ID进行配置:{  "Statement": [    {      "Sid": "Stmt1375240018062",      "Action": [        "*"      ],      "Effect": "Allow",      "Resource": "my-bucket123",      "Principal": {        "ID": [          "domain/c41**************************8cf:user/053**************************2c4 "        ]      }    },    {      "Sid": "Stmt1375240018063",      "Action": [        "Get*"      ],      "Effect": "Allow",      "Resource": "my-bucket123/*",      "Principal": {        "ID": [          "domain/c41**************************8cf:user/053**************************2c4 "        ]      }    }  ]}Demo代码如下:package samples_java;import com.obs.services.ObsClient;import com.obs.services.ObsConfiguration;import com.obs.services.exception.Ob**ception;import java.io.IOException;public class BucketTestSample {     private static final String endPoint = "XXX";     private static final String ak = "XXX";     private static final String sk = "XXX";     private static ObsClient obsClient;     private static String bucketName = "my-bucket123";         public static void main(String[] args)             throws IOException {         ObsConfiguration config = new ObsConfiguration();         config.setSocketTimeout(30000);         config.setConnectionTimeout(10000);         config.setEndPoint(endPoint);         try {             obsClient = new ObsClient(ak, sk, config);             String  Policy = "{\"Statement\":[{\"Sid\":\"Stmt1375240018062\",\"Action\":[\"*\"],\"Effect\":\"Allow\",\"Resource\":\"my-bucket123\",\"Principal\":{\"ID\":[\"domain/c41**************************8cf:user/053**************************2c4\"]}},{\"Sid\":\"Stmt1375240018063\",\"Action\":[\"Get*\"],\"Effect\":\"Allow\",\"Resource\":\"my-bucket123/*\",\"Principal\":{\"ID\":[\"domain/c41**************************8cf:user/053**************************2c4\"]}}]}";             obsClient.setBucketPolicy(bucketName,Policy);         } catch (Ob**ception e) {             System.out.println("Response Code: " + e.getResponseCode());             System.out.println("Error Message: " + e.getErrorMessage());             System.out.println("Error Code:       " + e.getErrorCode());             System.out.println("Request ID:      " + e.getErrorRequestId());             System.out.println("Host ID:           " + e.getErrorHostId());         } finally {             if (obsClient != null) {                 try {                     obsClient.close();                 } catch (IOException e) {                     System.out.println(e);                 }             }         }     } }3      效果展示设置后的桶策略如下:userB在桶内上传文件失败(没有权限),下载文件成功4      附录OBS JAVA SDK使用,官网参考链接:https://support.huaweicloud.com/sdkreference-obs/obs_02_0001.html更多桶策略的具体格式(JSON格式字符串)请参考《对象存储服务API参考》:https://support.huaweicloud.com/api-obs/zh-cn_topic_0100846742.html
  • [技术干货] OBS JAVA SDK 实践7:已存在对象如何修改对象名称、对象属性、以及注意事项
    1      已存在对象如何修改对象名称目前已经上传到OBS桶中的对象名称是不可修改的(后续OBS会上线POSIX语义桶,可能会支持),如果想修改已经存在的对象名称,可以通过复制旧对象到新对象,再将旧对象删除来实现。以OBS JAVA SDK为例,复制对象操作,参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815454.html;删除对象操作,参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815453.html。2      已存在对象如何修改对象属性对象元数据有很多,比如Object文件类型Content-Type、指定Object被下载时的网页的缓存行为Cache-Control、还可以自定义元数据x-obs-meta-*,具体可以参考API接口链接说明:https://support.huaweicloud.com/api-obs/zh-cn_topic_0137044900.html。已经上传到OBS桶中的对象属性不可以直接修改,(后续OBS SDK会上线此功能),目前可通过带对象属性覆盖上传同名对象来达到效果(参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815529.html),也可以通过带对象属性复制同名对象来达到效果(参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815454.html)。注:若OBS桶开启了多版本,通过对象覆盖对象和复制对象来达到修改对象属性时若不带版本进行操作,会产生多余的新版本对象,占用额外的存储空间3      附录链接OBS JAVA SDK使用方法,官网参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815558.html
  • [技术干货] OBS JAVA SDK 实践6:转换已存在对象存储类型
    1      背景介绍 & 效果展示OBS提供三种存储类型:标准存储、低频访问存储或归档存储。低频访问存储的对象可以修改为标准存储或归档存储的对象。归档存储的对象要先恢复,才可以修改为标准存储或低频访问存储。本文通过JAVA SDK实现将对象从标准存储转换为归档存储,以及归档存储到低频访问存储的转换,效果如下。注:有关标准存储、低频访问、归档存储三种存储类型的更多信息,参考链接:https://support.huaweicloud.com/usermanual-obs/zh-cn_topic_0050321036.html图1 原始对象图2 对象从标准存储转换为归档存储图3 对象从归档存储转换为低频访问存储2      java代码参考(对象从标准存储转换为归档存储)前提:需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。                  public static void main(String[] args) throws IOException {                   // 需要将endPoint/ak/sk更新为实际信息                   String endPoint = "https://your-endpoint";                   String ak = "*** Provide your Access Key ***";                   String sk = "*** Provide your Secret Key ***";                                      // 创建ObsClient实例                   ObsClient obsClient = new ObsClient(ak, sk, endPoint);                   try                  {                                      String bucketName = "bucketXXX";                // 需要将bucketName更新为实际信息                                       String objectName = "objectXXX";                // 需要将objectName更新为实际信息CopyObjectRequest request = new CopyObjectRequest(bucketName, objectName, bucketName, objectName);                              request.setReplaceMetadata(true);                                        ObjectMetadata newObjectMetadata = new ObjectMetadata();                                        newObjectMetadata.setContentType("image/jpeg");           // 修改对象的ContentType                                        newObjectMetadata.setObjectStorageClass(StorageClassEnum.COLD);              // 转换为归档存储                                        request.setNewObjectMetadata(newObjectMetadata);                                        CopyObjectResult result = obsClient.copyObject(request);                                        System.out.println("\t" + result.getStatusCode());                  }                  catch (Ob**ception e)                  {                      System.out.println("Response Code: " + e.getResponseCode());                      System.out.println("Error Message: " + e.getErrorMessage());                      System.out.println("Error Code:       " + e.getErrorCode());                      System.out.println("Request ID:      " + e.getErrorRequestId());                      System.out.println("Host ID:           " + e.getErrorHostId());                  } }3      java代码参考(对象从归档存储转换为低频访问存储)前提:需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。                  public static void main(String[] args) throws IOException {                   // 需要将endPoint/ak/sk更新为实际信息                   String endPoint = "https://your-endpoint";                   String ak = "*** Provide your Access Key ***";                   String sk = "*** Provide your Secret Key ***";                                      // 创建ObsClient实例                   ObsClient obsClient = new ObsClient(ak, sk, endPoint);                   try                  {                                      String bucketName = "bucketXXX";                // 需要将bucketName更新为实际信息                                       String objectName = "objectXXX";                // 需要将objectName更新为实际信息                                        // 快速取回归档对象RestoreObjectRequest request1 = new RestoreObjectRequest();                                        request1.setBucketName(bucketName);                                        request1.setObjectKey(objectName);                                        request1.setDays(1);                                        request1.setRestoreTier(RestoreTierEnum.EXPEDITED);                                        obsClient.restoreObjectV2(request1);                                        // 等待对象取回                                        Thread.sleep(60 * 6 * 1000);                                         CopyObjectRequest request = new CopyObjectRequest(bucketName, objectName, bucketName, objectName);                                        ObjectMetadata newObjectMetadata = new ObjectMetadata();                                        newObjectMetadata.setObjectStorageClass(StorageClassEnum.WARM);              // 转换为低频访问存储                                        request.setNewObjectMetadata(newObjectMetadata);                                        CopyObjectResult result = obsClient.copyObject(request);                                        System.out.println("\t" + result.getStatusCode());                  }                  catch (Ob**ception e)                  {                      System.out.println("Response Code: " + e.getResponseCode());                      System.out.println("Error Message: " + e.getErrorMessage());                      System.out.println("Error Code:       " + e.getErrorCode());                      System.out.println("Request ID:      " + e.getErrorRequestId());                      System.out.println("Host ID:           " + e.getErrorHostId());                  } }4      附录链接OBS JAVA SDK使用方法,官网参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815558.html
  • [技术干货] OBS JAVA SDK 实践5:判断文件是否存在
    1      背景介绍 & 效果展示通过JAVA SDK可判断文件是否存在,并不需要下载对象操作,如果对象存在会返回对象的类型和对象大小,若对象不存在则返回相应的错误码,效果如下。图1 对象存在会返回对象的类型和对象大小图2 对象不存在则返回相应的错误码2      java代码参考前提:需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。                  public static void main(String[] args) throws IOException {                   // 需要将endPoint/ak/sk更新为实际信息                   String endPoint = "https://your-endpoint";                   String ak = "*** Provide your Access Key ***";                   String sk = "*** Provide your Secret Key ***";                                      // 创建ObsClient实例                   ObsClient obsClient = new ObsClient(ak, sk, endPoint);                   try                  {                                        String bucketName = "bucketXXX";                // 需要将bucketName更新为实际信息                                       String objectName = "objectXXX";                // 需要将objectName更新为实际信息                                      ObjectMetadata metadata = obsClient.getObjectMetadata(bucketName, objectName);                                            System.out.println("---------------\nobject exist!");                                      System.out.println("\tcontentType: " + metadata.getContentType());                                      System.out.println("\tcontentLength: " + metadata.getContentLength());                  }                  catch (Ob**ception e)                  {                      System.out.println("Response Code: " + e.getResponseCode());                      System.out.println("Error Message: " + e.getErrorMessage());                      System.out.println("Error Code:       " + e.getErrorCode());                      System.out.println("Request ID:      " + e.getErrorRequestId());                      System.out.println("Host ID:           " + e.getErrorHostId());                                            if(e.getResponseCode() == 404) {                             System.out.println("---------------\nobject doesn't exist!");                      }                  } }3      附录链接OBS JAVA SDK使用方法,官网参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815558.html
  • Java语言的品味
    我一直在思考这节课应该叫个什么名字。想来想去,觉得taste of java这个名字最好。随着编程经验的丰富,使用的编程语言也多起来。不同语言之间难免会进行对比。而语言的设计者在设计一门语言时,要面临很多问题,而且这些问题并没有完美的答案,而如何进行取舍很多时候真的就是一个理念,甚至是品味的问题了。Java是一门面向对象的语言不用进行深入地学习,只要是听说过Java的人,都知道Java是一门面向对象的语言。其实面向对象往宽泛了说,应该是一种编程思想,它是一种思维方式。而面向对象的编程语言则是指,编程语言提供了一种机制,使得我们可以用比较简洁的语法表达数据的抽象和封装。例如,PostgreSQL这个数据库就是用C编写的,但是它的源代码却很有趣,用struct 定义了很多结构体,然后用struct的嵌套模拟了类的继承(要知道,在C++中,struct甚至都可以和class换用),而对象的布局在结构体里也显得更加清晰。这也是一种面向对象的编程方式,但我们却不认为C是一种面向对象的编程语言,这是因为C并不提供方便的语法让我们轻松地使用面向对象编程。而C++, Java, Python这些语言则提供了class关键字来进行类的定义,我们会说这些语言是面向对象的。我们知道,C++里是可以定义全局变量,全局函数的。很多脚本语言,虽然是面向对象,但仍然可以在类定义之外声明变量,定义函数,执行操作。举个最简单的例子,我们看几种语言的hello world// C++的写法 int main() {     cout << "hello world" << endl;     return 0; } # Python 的写法 print "hello world" // Scala的写法 println("hello world") /* Java 的写法 */ public class Main {     public static void main(String args[]) {         System.out.println("hello world");     } }很明显,Java最啰嗦,C++次之,python和scala就都比较简洁。从这个简单的例子就能看出来语言的不同品味。python和scala倾向于灵活,一个具体的操作可以脱离函数实体而直接运行。C++就会严谨一些,所有的动作都必须被封装到函数中去,然后通过执行一个函数来做一些事情(比如往控制台打印字符)。而Java的要求就更严格了,Java要求语言中,所有的函数都必须定义在一个类里,函数不能脱离类而存在。这样的规定使得Java显得死板,但有时候太过灵活,反而很难掌握。比如scala,内部分裂为两个流派,一派把scala做为Java的改进,另一派完全使用函数式编程,而不主张对Java进行改进。对于初学者,在还没掌握一门语言的全貌之前,就听各种“专家”,“大牛”大谈编程范式,相互鄙视,然后听了一堆似是而非的概念,其实是有害的。但是Java不同,语法的死板意味着更少的歧义。强对象使得Java成为了学习面向对象编程的最佳入门语言。面向对象的不足凡是有利必有弊,强对象编程,使得语法简单统一,但也有其缺点,而且有很多。我们在接下来的课程里会一点点接触到。我们今天先看第一个。有些变量和函数确实没必要定义在一个类里。强行规定这些函数在类里,反而显得累赘。想一个例子,比如正弦函数sin,常数PI,这些函数或者常量值为什么要定义在类里呢?一定要定义的话,定义在哪个类里合适呢?Java的做法是把数学函数封装到一个叫做Math的类里。叹气...一个叫Math的类,太不直观了。再来思考一个问题,如果说,我们这样写class Math {     public double sin(double x) {/*code goes here*/} }那么,我每次要调用sin函数都得写成new Math().sin(x)因为,我们只能通过Math类型的对象去调用定义在Math类中的函数。这太不科学了。为了调用一个本来可以全局存在的函数,我们却要新建一个对象?!语言的设计者肯定也不会这么傻。于是,他们引入了static这个关键字。Static关键字当我们把一个函数或者变量加上static限制以后,就可以在不创建一个对象的情况下,直接使用类里的函数或者变量了。class Math {     public static double sin(double x) {/*code goes here*/} } Math.sin(x)编程语言的关键字是有它内在的逻辑的,不要去死记硬背,通过上面的分析,我们就能知道static关键字用于修饰变量和函数是不得不这样做,而不是大家闲得慌,去加这么一个关键字故意去难为新手们。好了,有了static关键字,世界好像变得合理了一点。但是做为语言设计者,还是不满意,如果我有一个程序,里面会用到大量的数学函数,然后我就看到了满屏幕的Math.xxxhttp://MatM。要是能把这个Math去掉就好了。然后设计者们就把主意打到了import那里。我们能不能把这些本来就是全局函数,全局常量的值导入到当前文件中,好像他们本身就没有被封装到类里一样?于是这种语法就出现了:import static java.lang.Math.*; public class Main {     public static void main(String args[]) {         System.out.println(sin(PI / 2));     } }好了,通过这种方法,就把Math中的所有static方法和常量都引入到当前文件了,我们再也不用使用Math开头去引用一个静态函数了。其实static的语义到这一步就基本说清楚了。如果我是Java的设计者,我不会再为static增加其他用法了。但是不幸的是,Java有一个坏品味,那就是重用关键字。这让一些本来简单的事情又变复杂了。static关键字还可以用来定义静态代码块。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。这种与类加载有关的逻辑,显然应该甩锅给ClassLoader。比如 ClassLoader在加载一个类的时候,调用类中的static onLoad()方法,也比静态代码块这种引起混淆的语法好。这样的设计才会显得清晰。静态代码块是什么鬼!?这显然是一个关键字复用的错误例子。我们没办法改变这种设计,只能去适应。记住这个用法吧。static 函数里不能使用this, super?废话!你只要明白了static 函数其实是全局函数,它只是因为Java的强对象的要求,而不得不找个类“挂靠”,它本身与任何类都没有关系。所以在static 方法里,当然不能直接访问某一个类的成员变量和成员函数了。但是呢,一个类让一个static函数挂靠了,总得有点好处吧?要说好处,倒也有一个,那就是类的成员函数调用static方法不用带类名了。class Example {     public static void sayHello() {         System.out.println("Hello, everybody~");         // 这个当然不能用。static函数与其挂靠的那个类的对象没有任何关系。        // static函数是全局唯一的。        // this.sayBye();    }        public void sayBye() {         System.out.println("Good Bye~");     }        public void saySomething() {         // 唯一的一点好处,大概就是成员函数里这样三种写法都是OK的。        // 但这个没卵用。我更喜欢Java只保留第三种写法,免得大家误会。        this.sayHello();         sayHello();         Example.sayHello();         this.sayBye();     } }final关键字final 用于修饰一个类,那么这个类就不能再被其他类继承。用于修饰一个方法,这个方法不能被覆写。这是非常好的一个东西。可以避免我们造出混乱的继承结构。比如Java中的String类就是final的,它是不能被继承的。// 想创建一个自己的String类是不行的。因为String是final的。class MyString extends String {}再看修饰method的情况:class A {      public final void f() {     }        // 这里是OK的,只是一次重载     public final void f(int a) {     }    } class B extends A {      // 会报错,说f是final的,不能覆写     public void f() {     }    }好。到此为止,final是如此地清晰。但不幸的是,Java的设计者不知道是出于什么考虑,把final也拿来定义变量。这就让人无语了。这是const关键字做的事情啊。重用关键字决不会让语法变得更简洁。对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。而且,事实证明,Java的final和C++的const还真就是同样的。就连一些容易混淆的地方都原封不动地迁移过来。我们挨着看。先看基本用法。final int a = 1; a += 2; // 会报错,我们不能修改一个final变量再看一下容易引起混乱的地方。public class Hello {     public static void main(String args[]) {         String a = "go die, ";         final String b = "final";         String c = "go die, " + b;         String d = a + b;         String e = "go die, final";         System.out.println(e == c); //true,比较两个变量是否指向同一个对象         System.out.println(e == d); //false         System.out.println(c.equals(d));//true,比较两个字符串的值是否相同     } }结果可能出乎你的意料。我来解释一下。在编译阶段,变量c其实已经是"go die, final"了,等到我们后面分析Java字节码文件的时候就会看到,c和e是指向了常量池中的同一个字符串,也就是“go die, final"。所以它们其实是同一个对象。但是d却是运行时生成的,并不引用常量池中的"go die, final"这个字符串,所以,e和d并不是同一个对象,虽然它们的值相同。这和C++中编译时const变量转成编译时常量如出一辙。究其根本原因,还是在于b 在编译阶段就已经被当作常量“final” 去做下面的编译了。final关键字被用来当做const用,实在不是个好的品味。当然,const这个关键字是保留字,就是说在Java中虽然现在没用,但不保证以后不会用。你是不能拿这个词来当变量名的。额外加一句,如果一个变量在整个执行阶段不会被修改,那么加上final进行修饰是一个好的编程习惯。好了。我们今天通过static 和 final 这两个关键字来初步了解了一下Java的设计品味。语言的设计品味是一个很大的话题。我们会就这个话题继续我们的课程。
  • [技术干货] OBS JAVA SDK 实践3:列举指定目录下的所有文件、列举指定目录下的文件和子目录
    1      背景介绍 & 效果展示可以通过JAVA SDK,列举指定目录下的所有文件,也可以列举指定目录下的文件和子目录,效果如下。图1 指定目录share/下的所有文件图2 列举指定目录下的所有文件图3 列举指定目录下的文件和子目录2      java代码参考(列举指定目录下的文件和子目录)前提:需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。           String endPoint = "https://your-endpoint";                   String ak = "*** Provide your Access Key ***";                   String sk = "*** Provide your Secret Key ***";                                      // 创建ObsClient实例                   ObsClient obsClient = new ObsClient(ak, sk, endPoint);                                                         ListObjectsRequest request = new ListObjectsRequest("chongchongtest");                   // 设置文件夹对象名"share/"为前缀                   request.setPrefix("share/");                   request.setMaxKeys(1000);                    ObjectListing result;                    System.out.println("Objects:");                   do{                       result = obsClient.listObjects(request);                       for (ObsObject obsObject : result.getObjects())                       {                           System.out.println("\t" + obsObject.getObjectKey());                       }                       System.out.println("------------------------------");                       request.setMarker(result.getNextMarker());                   }while(result.isTruncated()); 3      java代码参考(列举指定目录下的所有文件)前提:需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。String endPoint = "https://your-endpoint";                   String ak = "*** Provide your Access Key ***";                   String sk = "*** Provide your Secret Key ***";                                      // 创建ObsClient实例                   ObsClient obsClient = new ObsClient(ak, sk, endPoint);                                      ListObjectsRequest request = new ListObjectsRequest("chongchongtest");                   // 设置文件夹对象名"share/"为前缀                   request.setPrefix("share/");                   request.setDelimiter("/");                   request.setMaxKeys(500);                    ObjectListing result;                    // 列举文件                   System.out.println("Objects:");                   do{                       result = obsClient.listObjects(request);                       for (ObsObject obsObject : result.getObjects())                       {                           System.out.println("\t" + obsObject.getObjectKey());                       }                       System.out.println("------------------------------");                       request.setMarker(result.getNextMarker());                   }while(result.isTruncated());                                      // 列举子目录                   System.out.println("\nFolder:");                   do{                       result = obsClient.listObjects(request);                       for (String commonPrefix : result.getCommonPrefixes())                       {                           System.out.println("\t" + commonPrefix);                       }                       System.out.println("------------------------------");                       request.setMarker(result.getNextMarker());                   }while(result.isTruncated());4      附录链接OBS JAVA SDK 列举对象其它使用方法,官网参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815500.html
  • [技术干货] OBS JAVA SDK 实践4:统计指定目录下的文件和子目录大小
    OBS JAVA SDK 实践4:统计指定目录下的文件和子目录大小1      背景介绍 & 效果展示可以通过JAVA SDK统计指定目录下的文件和子目录大小,效果如下。图1 指定目录share/下的所有文件图2 统计指定目录下的文件和子目录大小2      java代码参考前提:需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。                  public static void main(String[] args) throws IOException {                                      String endPoint = "https://your-endpoint";                   String ak = "*** Provide your Access Key ***";                   String sk = "*** Provide your Secret Key ***";                                      // 创建ObsClient实例                   ObsClient obsClient = new ObsClient(ak, sk, endPoint);                                      String bucketName = "chongchongtest";                   ListObjectsRequest request = new ListObjectsRequest(bucketName);                   // 统计文件夹对象名"share/"下面的子目录和文件的大小                   request.setPrefix("share/");                   request.setDelimiter("/");                    ObjectListing result;                    // 统计文件夹下对象的大小                   System.out.println("Objects:");                   do{                       result = obsClient.listObjects(request);                       for (ObsObject obsObject : result.getObjects())                       {                             double objectSize = obsObject.getMetadata().getContentLength() / 1024.0;                           System.out.println("\t" + obsObject.getObjectKey() + ": " + String.format("%.2f", objectSize) + "KB");                       }                       System.out.println("------------------------------");                       request.setMarker(result.getNextMarker());                   }while(result.isTruncated());                                      // 统计子目录的大小                   System.out.println("\nFolder:");                   do{                       result = obsClient.listObjects(request);                       for (String commonPrefix : result.getCommonPrefixes())                       {                           double objectSize = countFolerLength(obsClient, bucketName, commonPrefix);                           System.out.println("\t" + commonPrefix + ": " + String.format("%.2f", objectSize) + "KB");                       }                       System.out.println("------------------------------");                       request.setMarker(result.getNextMarker());                   }while(result.isTruncated());          }                    //统计每个子目录的大小          private static double countFolerLength(ObsClient obsClient, String bucketName, String folder) {                                      double size = 0L;                                      ListObjectsRequest request = new ListObjectsRequest(bucketName);                   request.setPrefix(folder);                                      ObjectListing result;                   do{                       result = obsClient.listObjects(request);                       for (ObsObject obsObject : result.getObjects())                       {                           size += obsObject.getMetadata().getContentLength() / 1024.0;                       }                       request.setMarker(result.getNextMarker());                   }while(result.isTruncated());                                      return size;          }                   3      附录链接OBS JAVA SDK 列举对象其它使用方法,官网参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0142815500.html
  • [技术干货] (JAVA生成可执行文件)利用OBS API配置和查询桶历史对象CRR
    1      工具作用OBS提供跨区域复制(CRR)功能,此功能开通后,可以将同一个账号下一个桶(源桶)中的数据自动、异步地复制到不同区域的另外一个桶(目标桶)中,但启用跨区域复制功能之前上传的对象,不会被复制到目标桶。为了解决这个问题,CRR提供了历史对象CRR功能,开启此功能后,源桶中的所有数据都会自动、异步地复制到目标桶中,此功能的界面还未上线,但可以通过OBS API**送http、https请求来配置历史对象CRR功能,本文工具对API接口进行封装,使用者只需填写简单的配置信息即可启动桶历史对象CRR功能。2      效果展示源桶obs-chongchong-guangzhou中有1000个对象。使用工具启动源桶obs-chongchong-guangzhou到目的桶obs-chongchong-beijing的历史对象CRR,约10分钟后源桶中数据复制到北京region的目的桶obs-chongchong-beijing中。3      使用前准备工具使用前需要做如下准备:1)     运行工具的平台需要安装JAVA(JDK)4      工具使用详细步骤4.1      拷贝工具目录到工具运行平台将本文附录中的工具包链接(testCrrOld.zip)下载到Linux平台指定目录并解压,效果如下:     其中setBucketCrr.jar是工具jar包、application.properties是工具运行的配置文件、replicationOld-open.xml是配置历史对象CRR的XML内容。4.2      配置application.properties、replicationOld-open.xmlapplication.properties是工具运行的配置文件,需要将文件中的信息更新为实际信息。replicationOld-open.xml是配置历史对象CRR的XML内容,需要参考下表中解释将文件中的信息更新为实际信息。名称描述是否必须Agency用户创建的委托名字是ID规则的特殊辨识符否Prefix对象键值名的前缀,适配于一个或者多个对象。否Bucket规则适用的目的桶名称。是StorageClass对象的存储类型。有效值:STANDARD|WARM|COLD否注:XML中字段更详细的配置指导参考链接——https://support.huaweicloud.com/usermanual-obs/obs_03_0003.html4.3      运行工具使用命令“java –jar setBucketCrr.jar”运行工具,工具会**送OBS配置请求,同时还会返回查询配置的结果信息。5      附录工具下载链接:https://obs-tools.obs.cn-north-1.myhuaweicloud.com/crrApi/testCrrOld.zip
  • [技术干货] OBS JAVA SDK 实践2:模拟桶删的功能(删除非空桶)
    1      背景介绍目前OBS只支持删除空桶,如果桶中有数据,需要先删除桶中所有数据(包含多版本),之后才能删除桶。下面的代码模拟桶删的功能,展示如何一步到位删除非空桶。2      效果展示这里桶obs-chongchong-guangzhou桶中有约2000个对象数据,多个文件夹                                                 使用代码进行桶删后,在桶列表中已经找不到此桶3      java代码参考前提:需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。import java.io.IOException;import com.obs.services.ObsClient;import com.obs.services.ObsConfiguration;import com.obs.services.exception.Ob**ception;import com.obs.services.model.DeleteObjectsRequest;import com.obs.services.model.DeleteObjectsResult;import com.obs.services.model.ListVersionsRequest;import com.obs.services.model.ListVersionsResult;import com.obs.services.model.VersionOrDeleteMarker; public class BucketDelete {       private static ObsClient obsClient;        public static void main(String[] args) throws InterruptedException       {           try           {               String endPoint = "XXX";        // e.g "https://obs.cn-north-1.myhuaweicloud.com"               String ak = "XXX";                              // 对象所属的帐户ak               String sk = "XXX";                              // 对象所属的帐户sk                                                              String bucketName = "obs-chongchong-beijing";               // 需要填写为实际的桶名               obsClient = new ObsClient(ak, sk, endPoint);                                                               //列举桶中对象并删除               ListVersionsResult result = obsClient.listVersions(bucketName);                                                              if(result.getVersions().length != 0)               {                    ListVersionsRequest request = new ListVersionsRequest(bucketName);                    // 设置每次批量删除500个对象                    request.setMaxKeys(500);                    ListVersionsResult result1;                    do {                         result1 = obsClient.listVersions(request);                         DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest(bucketName);                         for(VersionOrDeleteMarker v  : result1.getVersions()) {                              deleteRequest.addKeyAndVersion(v.getKey(), v.getVersionId());                         }                                                                                                       DeleteObjectsResult deleteResult = obsClient.deleteObjects(deleteRequest);                         // 获取删除成功的对象                         System.out.println(deleteResult.getDeletedObjectResults());                                                                                                 request.setKeyMarker(result1.getNextKeyMarker());                         request.setVersionIdMarker(result1.getNextVersionIdMarker());                    }while(result.isTruncated());               }                                                                                                               //删除桶               obsClient.deleteBucket(bucketName);               System.out.println("\n------------------\nbucket already delete.");         }         catch (Ob**ception e)         {               e.printStackTrace();               System.out.println("Response Code: " + e.getResponseCode());               System.out.println("Error Message: " + e.getErrorMessage());               System.out.println("Error Code:       " + e.getErrorCode());               System.out.println("Request ID:      " + e.getErrorRequestId());               System.out.println("Host ID:           " + e.getErrorHostId());          }          finally          {               if (obsClient != null)                   {                       try                       {                            obsClient.close();                        }                        catch (IOException e)                            {                            }                        }                    }             }                         }   4      附录链接OBS JAVA SDK使用,官网参考链接:https://support.huaweicloud.com/sdkreference-obs/obs_02_0001.html
  • [技术干货] OBS JAVA SDK 实践1:如何生成带有图片处理功能的临时访问URL
    1      背景介绍如果想授予其他用户带有图片处理功能的对象操作权限,可以通过OBS SDK生成带有鉴权信息的URL,同时指定URL的有效期来限制访问时长,之后便可将URL提供给其它用户进行临时访问。2      效果展示这里利用第3章中代码生成的URL链接,将该链接打开后的效果如下(将图片进行了30度旋转),链接有效时间设置的60S有效60s过期后,再打开此URL链接时返回访问失败3      java代码参考前提:需要先下载OBS最新的JAVA SDK,参考官网链接:https://developer.huaweicloud.com/sdk?OBS,并在自己的项目中导入SDK中的JAR包。 import java.io.IOException;import java.util.HashMap;import java.util.Map;import com.obs.services.ObsClient;import com.obs.services.ObsConfiguration;import com.obs.services.model.HttpMethodEnum;import com.obs.services.model.TemporarySignatureRequest;import com.obs.services.model.TemporarySignatureResponse; public class temp {           public static void main(String[] args) throws IOException {                   // TODO Auto-generated method stub                                     String endPoint = "XXX";        // e.g "https://obs.cn-north-1.myhuaweicloud.com"                   String ak = "XXX";                     // 对象所属的帐户ak                   String sk = "XXX";                     // 对象所属的帐户sk                                     // 代理信息设置,没有不用设置                                ObsConfiguration config = new ObsConfiguration();                   config.setSocketTimeout(30000);                config.setConnectionTimeout(10000);                   config.setEndPoint(endPoint);                   config.setHttpProxy(proxyAddr, proxyPort, userName, passWord);               // 根据实际情况填写代理信息                   ObsClient obsClient = new ObsClient(ak, sk, config);                                                          long expireSeconds = 60L;              // 设置URL有效期,60秒                   Mapmap = new HashMap                   map.put("x-image-process", "image/resize,w_1000/rotate,30"); // 设置图片处理的效果,此处为宽度调整为1000旋转30度                    TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);                   request.setBucketName("obs-test-chongchong");             // 需要填写为实际的桶名                   request.setObjectKey("IMG_20190302_122501.jpg");                    // 需要填写为实际的对象名                   request.setQueryParams(map);                   TemporarySignatureResponse response = obsClient.createTemporarySignature(request);                   System.out.println("Getting object using temporary signature url:");                   System.out.println("\t" + response.getSignedUrl());                 // 输出临时URL                         }}4      附录链接OBS JAVA SDK使用,官网参考链接:https://support.huaweicloud.com/sdk-java-devg-obs/zh-cn_topic_0073679956.htmlOBS 图片处理使用,官网参考链接:https://support.huaweicloud.com/fg-obs/obs_01_0001.html
  • [分享交流] TensorFlow 队列与线程
    TensorFlow 队列与线程深度学习的模型训练过程往往需要大量的数据,而将这些数据一次性的读入和预处理需要大量的时间开销,所以通常采用队列与多线程的思想解决这个问题,而且TensorFlow为我们提供了完善的函数。本文介绍了TensorFlow的线程和队列。在使用TensorFlow进行异步计算时,队列是一种强大的机制。正如TensorFlow中的其他组件一样,队列就是TensorFlow图中的节点。这是一种有状态的节点,就像变量一样:其他节点可以修改它的内容。具体来说,其他节点可以把新元素**到队列后端(rear),也可以把队列前端(front)的元素删除。在Python中是没有提供直接实现队列的函数的,所以通常会使用列表模拟队列。而TensorFlow提供了整套实现队列的函数和方法,在TensorFlow中,队列和变量类似,都是计算图上有状态的节点。操作队列的函数主要有:l  FIFOQueue():创建一个先入先出(FIFO)的队列 l  RandomShuffleQueue():创建一个随机出队的队列 l  enqueue_many():初始化队列中的元素 l  dequeue():出队 enqueue():入队与队列Queue有关的有以下三个概念:l  Queue是TF队列和缓存机制的实现l  QueueRunner是TF中对操作Queue的线程的封装l  Coordinator是TF中用来协调线程运行的工具虽然它们经常同时出现,但这三样东西在TensorFlow里面是可以单独使用的,不妨先分开来看待。1.    Queue,队列根据实现的方式不同,分成具体的几种类型,例如:l  tf.FIFOQueue 按入列顺序出列的队列l  tf.RandomShuffleQueue 随机顺序出列的队列l  tf.PaddingFIFOQueue 以固定长度批量出列的队列l  tf.PriorityQueue 带优先级出列的队列l  ...这些类型的Queue除了自身的性质不太一样外,创建、使用的方法基本是相同的,以下介绍两个最常用的1)  tf.FIFOQueue(capacity, dtypes, name='fifo_queue') 创建一个以先进先出的顺序对元素进行排队的队列参数:capacity:整数。可能存储在此队列中的元素数量的上限dtypes:DType对象列表。长度dtypes必须等于每个队列元 素中的张量数,dtype的类型形状,决定了后面进队列元素形状方法:q.dequeue()获取队列的数据q.enqueue(值)将一个数据添加进队列q.enqueue_many(列表或者元组)将多个数据添加进队列q.size() 返回队列的大小2)、tf.RandomShuffleQueue() 随机出的队列Queue主要包含入列(enqueue)和出列(dequeue)两个操作。enqueue操作返回计算图中的一个Operation节点,dequeue操作返回一个Tensor值。Tensor在创建时同样只是一个定义(或称为“声明”),需要放在Session中运行才能获得真正的数值。下面是一个单独使用Queue的例子:#模拟同步操作   ''' 1.创建一个空的队列 2.向队列设置几个初始的值 3.从队列中取出一个数据,再将数据加1 4.数据加1之后的结果进队列 5.打印出队列中的数据 '''   def sync_test():     #创建一个空的队列     q = tf.FIFOQueue(3,tf.float32)     #向队列设置几个初始的值     enq_many = q.enqueue_many(([0.1,0.2,0.3],))       #从队列中取出一个数据,再将数据加1     out_q = q.dequeue()     data = out_q+1     #数据加1之后的结果进队列     en_q = q.enqueue(data)     with tf.Session() as sess:         sess.run(enq_many)           #执行en_q op 99次         for i in range(99):             sess.run(en_q)           #打印出队列中的数据         for i in range(q.size().eval()):             print(q.dequeue().eval())     return None  2.     QueueRunner,队列管理器tf.train.QueueRunner(queue, enqueue_ops=None)参数:l  queue:A Queuel  enqueue_ops:添加线程的队列操作列表,[]*2,指定两个线程l  create_threads(sess, coord=None,start=False) 创建线程来运行给定会话的入队操作l  start:布尔值,如果True启动线程;如果为False调用者 必须调用start()启动线程l  coord:线程协调器  用于线程的管理Tensorflow的计算主要在使用CPU/GPU和内存,而数据读取涉及磁盘操作,速度远低于前者操作。因此通常会使用多个线程读取数据,然后使用一个线程消费数据。QueueRunner就是来管理这些读写队列的线程的。QueueRunner需要与Queue一起使用(这名字已经注定了它和Queue脱不开干系),但并不一定必须使用Coordinator。看下面这个例子:import tensorflow as tf   import sys q = tf.FIFOQueue(10, "float") counter = tf.Variable(0.0)  #计数器 # 给计数器加一   increment_op = tf.assign_add(counter, 1.0)   # 将计数器加入队列   enqueue_op = q.enqueue(counter)     # 创建QueueRunner # 用多个线程向队列添加数据 # 这里实际创建了4个线程,两个增加计数,两个执行入队   qr = tf.train.QueueRunner(q, enqueue_ops=[increment_op, enqueue_op] * 2)     # 主线程   sess = tf.InteractiveSession() tf.global_variables_initializer().run()   # 启动入队线程   qr.create_threads(sess, start=True)   for i in range(20):     print (sess.run(q.dequeue()))增加计数的进程会不停的后台运行,执行入队的进程会先执行10次(因为队列长度只有10),然后主线程开始消费数据,当一部分数据消费被后,入队的进程又会开始执行。最终主线程消费完20个数据后停止,但其他线程继续运行,程序不会结束。3.    Coordinator,线程协调器tf.train.Coordinator() 线程协调员,实现一个简单的机制来协调一 组线程的终止方法: 返回的是线程协调实例            request_stop()  请求停止            join(threads=None, stop_grace_period_secs=120) 等待线程终止Coordinator是个用来保存线程组运行状态的协调器对象,它和TensorFlow的Queue没有必然关系,是可以单独和Python线程使用的。例如:#模拟异步操作   '''   通过队列管理器来实现变量加1,入队,主线程出队列的操作,观察效果? (异步操作) '''   def async_test():     # # 1、定义一个队列,1000     q = tf.FIFOQueue(300,tf.float32)       # 2、定义要做的事情 循环值,+1, 放入队列当中     var = tf.Variable(0.0)     # 实现一个自增  tf.assign_add     data = tf.assign_add(var,tf.constant(1.0))     en_q = q.enqueue(data)       # 3、定义队列管理器op, 指定多少个子线程,子线程该干什么事情     # 1,2,3,4,5,6,7,8,9,10     qr = tf.train.QueueRunner(q, enqueue_ops=[en_q] * 2)       # 初始化变量的OP     init_op = tf.global_variables_initializer()       with tf.Session() as sess:         #运行初始化op         sess.run(init_op)         # 开启线程管理器,coord线程协调器         coord = tf.train.Coordinator()         # 真正开启子线程,读数据入队列,t1,t2  0.0001  10         threads = qr.create_threads(sess, coord=coord, start=True)           # 主线程,不断读取数据训练  t0         for i in range(300):             #             print(sess.run(q.dequeue()))         print("size==>",sess.run(q.size()))         # 停止子线程,回收         coord.request_stop()         coord.join(threads)       return None 将这个程序运行起来,主线程会等待所有子线程都停止后结束,从而使整个程序结束。由此可见,只要有任何一个线程调用了Coordinator的request_stop方法,所有的线程都可以通过should_stop方法感知并停止当前线程。将QueueRunner和Coordinator一起使用,实际上就是封装了这个判断操作,从而使任何一个现成出现异常时,能够正常结束整个程序,同时主线程也可以直接调用request_stop方法来停止所有子线程的执行。 更多的技术内容,请访问腾科it教育集团网站 www.togogo.net
  • [问题求助] AgentLite java demo 中绑定的AgentLiteBind.java中PLATFORM_IP到底是哪个ip
  • [问题求助] Java消费方关闭隔离不生效
    依赖<groupId>com.huawei.paas.cse</groupId><artifactId>cse-solution-service-engine</artifactId><version>2.3.62</version>启动后压测,发现隔离策略被开启,并没有关闭,求助应该怎么样配置可以关闭隔离microservice.yaml配置如下:APPLICATION_ID: default # 应用名service_description:  name: ******      # 微服务名  version: 0.0.2  # 微服务版本  properties:    allowCrossApp: falsecse:  # 服务注册中心和配置中心的地址通过环境变量配置  service:    registry:      instance:        watch: false  config:    client:      refreshMode: 1      refresh_interval: 5000      #monitor:      #client:      #serverUri: https://cse.cn-north-1.myhuaweicloud.com  rest:    address: 0.0.0.0:28086    #When a local project is deployed as a container outside a cluster, you need to delete all monitor and credentials comments and configure the AK/SK.    #credentials:    #accessKey: ak    #secretKey: sk    #akskCustomCipher: default    #project: cn-north-1  servicecomb:  accesslog:    enabled: true # Enable access log.    pattern: "%{}enabler-access-log"  metrics:    window_time: 60000  # tick time, in ms    publisher:      defaultLog:        enabled: false    handler:    chain:      Consumer:        default: bizkeeper-consumer  isolation:      Consumer:        enabled: false        circuitBreaker:    Consumer:      enabled: false      forceOpen: false      forceClosed: true        fallback:    Consumer:      enabled: false        fallbackpolicy:    Consumer:      policy: throwexception      servicecomb:  handler:    chain:      Consumer:        default: loadbalance  loadbalance:    strategy:      name: RoundRobin    retryEnabled: true    retryOnNext: 2    retryOnSame: 0      
  • [问题求助] 运行平台北向java API Demo时出现问题
    最近在运行平台下载的北向java API Demo的消息订阅测试代码时,一直出现收到平台发过来的消息,例如我在平台portal工具删除了一个设备,然后就会一直收到deviceDelete类型的消息推送,代码未做任何修改,求解答!
  • [入驻式求助] vxml2.0的jsp调java接口时,,java接口返回的参数数据丢失问题
    【问题类别】vxml2.0 【问题现象描述】vxml2.0的jsp调java接口时,,java接口返回的参数数据丢失问题,丢失数据的参数从而变成undefined,,请问是什么原因导致数据丢失,如何避免?【日志或错误截图】java接口代码:java接口日志:jsp代码:jsp日志:
总条数:2294 到第 页
上滑加载中