【问题标题】:How to upload photos and other files in OpenStack Object Storage(Swift)如何在 OpenStack 对象存储(Swift)中上传照片和其他文件
【发布时间】:2014-01-14 02:45:48
【问题描述】:

我正在制作一个 Android 应用程序 并尝试存储文件,例如OpenStack object storage(Swift) 中的 docx、音乐、照片、视频使用它的 API。但是我在存储这些文件时遇到了问题。从我得到的 API 中,它只存储文件的名称,但是当我尝试从仪表板下载它时,对象本身就丢失了。

我从OpenStack Documentations 得到的 API 是这个。

方法: PUT 链接: (mylink)/v1/AUTH_(account)/(container)/(object)

标题 内容类型:(必填) X-Auth-Token:(必填) 内容长度:(可选) ETag:(可选) 内容处置:(可选) 内容编码:(可选) X-删除-在:(可选) X 对象元 PIN: X-删除-之后: X-对象-元

身体

我尝试上传的第一个文件是一张照片,我尝试将它作为二进制(base64)发送,因为在 API 中它也只接受字符串。我不知道把它放在哪里,所以我尝试在 Content-Disposition 中推送它,但它失败了。我不确定我还能把照片放在 openstack 可以接受的有限数据上的什么地方。

请帮忙。 我想查看我从手机上传的文件并从仪表板下载。

这是我的代码:

        HttpClient httpclient = new DefaultHttpClient();
        HttpPut httpost = new HttpPut("mylink/v1/AUTH_fa6362c6520449f9a8905e84fee68f8c/photos/"+imagename);
        try {   
              httpost.setHeader("X-Auth-Token", "nasbfdblfdfsdfsdfd123a");              
              httpost.setHeader("Content-Type", "application/octet-stream");    
              httpost.setHeader("Content-Length ", Integer.toString(binaryimagelength) );   
              httpost.setHeader("Content-Disposition ",  binaryimage);// this is path of the image from the phone memory (e.g. )    

             Log.i("", "pushing your data");    

             HttpResponse response=httpclient.execute(httpost);
             ResponseHandler<String> responseHandler = new BasicResponseHandler();
             String response2 = httpclient.execute(httpost, responseHandler);
             Log.i("", "Response1:   " + response.getStatusLine());
             Log.i("", "Response2:   " + response2);


        }catch (IOException e) {                    
            Log.e("", "IOException " + e.toString());
            // TODO Auto-generated catch block

            AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this,AlertDialog.THEME_DEVICE_DEFAULT_LIGHT).create();
             alertDialog.setTitle("Error");
             alertDialog.setMessage(e.toString());
             alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                   // TODO Add your code for the button here.

                }
             });
             alertDialog.show();
        } 

【问题讨论】:

    标签: java android api openstack openstack-swift


    【解决方案1】:

    在您的代码中,您将 content-disposition 指定为文件路径。

    尝试在那里指定文件对象。 那就是你从文件路径读取文件并使用 fileReadObject 设置内容处置。

    注意:我是 python 人。如果你希望我可以用 python 代码解释。

    【讨论】:

    • 您好,感谢您的回答。我尝试按照您的建议将特定对象放在那里。这是我的代码:Bitmap bm = BitmapFactory.decodeFile(imagepath); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);字节[] b = baos.toByteArray();我放了 httppost.setHeader("Content-Type": b),但它不允许任何不是字符串的东西。你有从文件路径读取文件并使用 fileReadObject 设置内容配置的示例代码格式吗?跨度>
    • 你能像 BufferedReader 一样将 ByteArray 转换为 String 吗?
    • @SyedHabibM 你能看看我的问题吗?它在python中,我有一个类似的问题。 stackoverflow.com/questions/32786418/…
    【解决方案2】:

    把它放在请求正文中。

    类似:

    httpost.setEntity(new FileEntity(new File(binaryimage)));

    【讨论】:

      【解决方案3】:

      我看到了你的问题,你启发了我编写自己的代码,所以在这里,我希望它对你有用

      public int uploadToSwift(String filePath, String container) {
          File file = new File(filePath);
          String fileName = file.getName();
          long binaryLength = file.length();
          int statusCode;
      
          // Start http communications
          HttpClient httpclient = HttpClientBuilder.create().build();
          System.out.println("Communicating to: http://"+IP+"/v1/AUTH_e3fb300a1a1d48d49fb6512658eaebf5/"+container+"/"+fileName);
          HttpPut httpost = new HttpPut("http://"+IP+":8080/v1/AUTH_e3fb300a1a1d48d49fb6512658eaebf5/"+container+"/"+fileName);
          try {   
                httpost.setHeader("X-Auth-Token", openStackToken);              
                httpost.setHeader("Content-Type", "application/octet-stream");    
                httpost.setHeader("Content-Length ", Long.toString(binaryLength) );
                httpost.setEntity(new FileEntity(file));
               System.out.println("Sending your data: " + fileName);    
      
               HttpResponse response = httpclient.execute(httpost);
               statusCode = response.getStatusLine().getStatusCode();
               // A file was placed on the container
               if(statusCode == 201){
                   System.out.println(response.getStatusLine());
                   Header[] headers = response.getAllHeaders();
                   for(Header header : headers)
                       System.out.println(header.getName() + " " + header.getValue());
               } else {
                   System.out.println(response.getStatusLine());
               }
      
          }catch (IOException e) {                    
              System.out.println("IOException " + e.toString());
              return 500;
          } 
          return statusCode;
      }
      

      【讨论】:

        【解决方案4】:

        您可以通过此代码上传文件

        public void uploadFileSmart(MyAsyncTask<Object, Integer, Boolean> task, Uri selectedFile, String parentId)
                throws IOException, NoInternetConnectionException, NotLoggedInException, UnexpectedStatusCodeException,
                FileNotFoundException, UnauthorizedException {
        
            if (!Utils.isNetworkConnected(context)) {
                throw new NoInternetConnectionException();
            }
        
            if (!isLoggedin) {
                throw new NotLoggedInException();
            }
        
            InputStream fis = context.getContentResolver().openInputStream(selectedFile);
        
            // TODO: do get filename and filesize in a functions.
            String fileName = "";
            long fileSize = 0;
            String scheme = selectedFile.getScheme();
            if (scheme.equals("file")) {
                File file = new File(selectedFile.getPath());
                fileName = file.getName();
                fileSize = file.length();
            } else if (scheme.equals("content")) {
        
                String[] proj = {"_data"};
                Cursor cursor = context.getContentResolver().query(selectedFile, proj, null, null, null);
                if (cursor.moveToFirst()) {
                    File file = new File(cursor.getString(0));
                    fileName = file.getName();
                    fileSize = file.length();
                } else {
                    throw new IOException("Can't retrieve path from uri: " + selectedFile.toString());
                }
            }
        
            /*
            if (fileName.length() == 0 || fileSize == 0) {
                throw new IOException("File name is empty or file size is 0.");
            }
            */
        
            String path = "/stacksync/files";
            List<Pair<String, String>> params = new ArrayList<Pair<String, String>>();
            params.add(new Pair<String, String>("file_name", fileName));
            params.add(new Pair<String, String>("overwrite", Boolean.TRUE.toString()));
        
            if (parentId != null) {
                params.add(new Pair<String, String>("parent", parentId));
            }
        
            String urlString = Utils.buildUrl(storageURL, path, params);
        
            URL url = new URL(urlString);
        
            long startTime = System.currentTimeMillis();
            Log.i(TAG, "Uploading file: " + urlString);
        
            // Open a connection to that URL.
            HttpsURLConnection ucon = (HttpsURLConnection) url.openConnection();
        
            ucon.setRequestMethod("PUT");
            ucon.addRequestProperty(FilesConstants.X_AUTH_TOKEN, authToken);
            ucon.addRequestProperty(FilesConstants.STACKSYNC_API, "True");
        
            // this timeout affects how long it takes for the app to realize
            // there's a connection problem
            ucon.setReadTimeout(connectionTimeout);
        
            ucon.setDoOutput(true);
        
            ucon.connect();
        
            OutputStream os = ucon.getOutputStream();
        
            BufferedInputStream bfis = new BufferedInputStream(fis);
            byte[] buffer = new byte[1024];
            int len;
            int total = 0;
            int lastUpdated = 0;
            int percent = 0;
        
            while ((len = bfis.read(buffer)) > 0) {
                total += len;
                percent = (int) (total * 100 / fileSize);
                if (lastUpdated != percent) {
                    task.setProgress(percent);
                    lastUpdated = percent;
                }
        
                os.write(buffer, 0, len);
            }
        
            task.setProgress(100);
        
            // clean up
            os.flush();
            os.close();
            bfis.close();
        
            int statusCode = ucon.getResponseCode();
        
            if (statusCode >= 200 && statusCode < 300) {
                Log.i(TAG, "upload completed in " + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
        
            } else if (statusCode == HttpStatus.SC_UNAUTHORIZED) {
                isLoggedin = false;
                throw new UnauthorizedException();
            } else {
                Log.e(TAG, "Unexpected status code: " + statusCode);
                throw new UnexpectedStatusCodeException("Status code: " + statusCode);
            }
        }
        

        更多访问https://github.com/stacksync/android图书馆

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-04
          • 1970-01-01
          相关资源
          最近更新 更多