【问题标题】:Cannot read a file using cordova file plugin in an Ionic 2 project无法在 Ionic 2 项目中使用 Cordova 文件插件读取文件
【发布时间】:2017-05-23 00:32:33
【问题描述】:

我正在尝试使用Cordova file plugin 来读取保存在移动设备中的图像,这样我就可以获得它的base64 编码,我需要远程存储它。问题是 resolveLocalFilesystemUrl() 方法,它应该提供一个 File Entry 对象,而不是似乎返回一个 Entry 对象,这意味着我不能在它上面调用 file。

这是应该获取文件条目对象的代码,因此我可以使用文件方法来读取文件本身。

MediaCapture.captureImage().then((images)=>{
  self.image = images[0].localURL;
  File.resolveLocalFilesystemUrl(self.image).then((entry)=>{
    entry.file(function (file) {
      var reader = new FileReader();

      reader.onloadend = function (encodedFile) {
        var src = encodedFile.target.result;
        src = src.split("base64,");
        var contentAsBase64EncodedString = src[1];
      };
      reader.readAsDataURL(file);
    })
  }).catch((error)=>{
    console.log(error);
  })
})

我收到以下 Typescript 错误,它告诉我 resolveLocalFilesystemUrl() 正在使用没有文件方法的 Entry 对象进行解析。 (插件文档说resolveLocalFilesystemUrl用一个File Entry对象解析,这样一个对象肯定有一个提供文件本身的file方法):

Property 'file' does not exist on type 'Entry'. 

我已经尝试过我提供的路径类型 resolveLocalFilesystemUrl()。我已经尝试了沿 /var/mobile/Applications//Documents/path/to/file 行的完整路径和沿 cdvfile://localhost/temporary/filename 行的本地 URL - 都不起作用

所以具体的问题是为什么 resolveLocalFilesystemUrl() 不为我提供一个文件条目对象,或者我如何让它这样做?更一般地说,如果上述方法不起作用,我如何在 Ionic 2 中读取文件以便获得它的 base64 版本。

谢谢!

【问题讨论】:

    标签: typescript base64 ionic2 cordova-plugins


    【解决方案1】:

    我在 Ionic3 中遇到了与@ionic-native/camera 类似的问题,错误是由destinationType: this.camera.DestinationType.FILE_URI 给出的,我解决了它,将其更改为destinationType: this.camera.DestinationType.DATA_URL。这就是我的项目的样子:

    import { Camera, CameraOptions } from '@ionic-native/camera';
    import { Image } from '****';
    
    export class CameraService {
      public readonly cameraOptions: CameraOptions = {
        sourceType: this.camera.PictureSourceType.CAMERA,
        destinationType: this.camera.DestinationType.DATA_URL,
        encodingType: this.camera.EncodingType.JPEG,
        mediaType: this.camera.MediaType.PICTURE,
        correctOrientation: true
      };
    
      constructor(public camera: Camera) { }
    
      public takePicture(): Observable<Image> {
        return Observable.fromPromise(this.camera.getPicture(this.pictureOptions)).map(imageSrc => {
          this.base64Image = 'data:image/jpeg;base64,' + imageSrc;
          return new Image('CameraPhoto.jpeg', this.base64Image);
        });
      }
    }
    

    类图像看起来像

    export class Image {
      public readonly name: string;
      public readonly fileURI: string;
      public readonly file?: File;
    
      constructor(name: string, fileURI: string, file?: File) {
        this.name = name;
        this.fileURI = fileURI;
        this.file = file;
      }
    }
    

    我希望它可以帮助某人。 干杯!

    【讨论】:

      【解决方案2】:

      我发现这个问题与 Typescript 有关。 resolveLocalFilesystemUrl() 实际上是使用 File Entry 对象进行解析(当我将本地 url 作为文件路径传递给它时),但 Typescript 认为它是一个 Entry 对象,并且认为不能在其上调用 file()。

      下面通过告诉 Typescript entry 对象可以是任何类型来解决问题,因此可以调用任何函数或属性。

      MediaCapture.captureImage().then((images)=>{
        self.image = images[0].localURL;
        File.resolveLocalFilesystemUrl(self.image).then((entry: any)=>{
          entry.file(function (file) {
            var reader = new FileReader();
      
            reader.onloadend = function (encodedFile: any) {
              var src = encodedFile.target.result;
              src = src.split("base64,");
              var contentAsBase64EncodedString = src[1];
            };
            reader.readAsDataURL(file);
          })
        }).catch((error)=>{
          console.log(error);
        })
      })
      

      请注意,我还必须使用 encodedFile: any 才能允许在 encodedFile 上调用 target.result

      【讨论】:

        【解决方案3】:

        那是因为resolveLocalFilesystemUrlwindow 对象的函数而不是文件。

        MediaCapture.captureImage().then((images)=>{
          self.image = images[0].localURL;
          window.resolveLocalFilesystemUrl(self.image).then((entry)=>{
            entry.file(function (file) {
              var reader = new FileReader();
        
              reader.onloadend = function (encodedFile) {
                var src = encodedFile.target.result;
                src = src.split("base64,");
                var contentAsBase64EncodedString = src[1];
              };
              reader.readAsDataURL(file);
            })
          }).catch((error)=>{
            console.log(error);
          })
        })
        

        或者您可以使用同一插件的离子原生版本here

        【讨论】:

        • 我正在使用插件的 Ionic Native 版本,这就是我在 File 上调用 resolveLocalFilesystemUrl 的原因。我实际上发现这个问题与 Typescript 有关——当我指定条目可以是任何类型时,问题就出现了,并且函数工作正常。我会添加一个答案供其他人参考...
        猜你喜欢
        • 2016-12-15
        • 2015-12-11
        • 2018-01-18
        • 1970-01-01
        • 2020-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-14
        相关资源
        最近更新 更多