代码之家  ›  专栏  ›  技术社区  ›  Danish Ajaib

如何将资产读取到inputFileStream?

  •  0
  • Danish Ajaib  · 技术社区  · 6 年前

    我的目标是将图像放在资产文件夹中,稍后将上载到Firebase存储。由于图像文件将与应用程序打包,我需要使用Firebase的putStream方法上载文件。但是,我无法将图像文件读入流。

    我所尝试的:

    public static InputStream readAssetsFileToStream(String fileName, Context context) {
        AssetManager assManager = context.getAssets();
        InputStream is = null;
        try {
            is = assManager.open(fileName);
        } catch (Exception e) {
            e.getMessage();
        } finally {
            try {
                if (is != null)
                    is.close();
            } catch (Exception e2) {
                e2.getMessage();
            }
        }
        InputStream isOutput = new BufferedInputStream(is);
        return isOutput;
    }
    

    然后在需要上载文件的位置:

    public  void uploadFile() throws IOException {
    
            Log.i("Firebase", "Upload started!");
    
           InputStream is = readAssetsFileToStream("abc", getApplicationContext());
    
    
    
            int size = is.available();
            byte[] buffer = new byte[size]; //declare the size of the byte array with size of the file
            is.read(buffer); //read file
            is.close(); //close file
    
            String streamData = new String(buffer);
         //   Uri file = Uri.fromFile(new File("path/to/raw/book.pdf"));sourc
    
          //  StorageReference riversRef = mStorageRef.child("/quadcopter.pdf");
    
    
            mStorageRef.putStream(is)
                    .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            // Get a URL to the uploaded content
                            Uri downloadUrl = taskSnapshot.getDownloadUrl();
                            Log.i("Firebase", downloadUrl.toString());
                            Log.i("Firebase", "Upload Successful!");
                        }
    
    
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {
                            Log.i("Firebase", "Upload failed");
                            Log.i("Firebase", exception.getMessage());
                            // ...
                        }
                    }).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                    Log.i("Firebase", "Upload Complete!");
    
                }
            }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                    Log.i("Firebase", String.valueOf(taskSnapshot.getBytesTransferred()));
                }
            });
        }
    

    上载文件时,我在以下位置收到错误:

        int size = is.available();
    

    也就是说,

    java.io.IOException: BufferedInputStream is closed
    

    我的项目结构:

    enter image description here

    我需要上传“abc”。jpg文件。非常感谢您的帮助。

    1 回复  |  直到 6 年前
        1
  •  1
  •   SWiggels    6 年前

    在你的最后一块 readAssetsFileToStream 关闭流:

    finally {
            try {
                if (is != null)
                    is.close();
            } catch (Exception e2) {
                e2.getMessage();
            }
    

    您总是返回一个封闭的流。可用性检查正确返回流已关闭。顺便说一句:您只能处理一次流。

    自AssetsManager起。open()可自动关闭,您可以编写:

    try(InputStream is = assManager.open(fileName)) {}
    

    并移除最后一个块。这将在使用后自动关闭您的流。

    但我建议您进行重构。返回流总是让您难以解决如何关闭流的问题。根据需要,您可以将其作为文件或字节[]返回。两者都有优势,也有各自的问题。