如何获取文件属性并从 ionic 4 上传文件?

How to get file properties and upload a file from ionic 4?

我正在尝试使用 ionic 4 将文件从移动设备上传到 google 存储桶。尽管文件可以上传到罐子里。我正在努力从文件对象中获取文件属性。

这是我的方法,

async selectAFile() {

    const uploadFileDetails = {
      name: '',
      contentLength: '',
      size: '',
      type: '',
      path: '',
    };

    this.fileChooser.open().then(uri => {

      this.file.resolveLocalFilesystemUrl(uri).then(newUrl => {
        let dirPath = newUrl.nativeURL;

        const dirPathSegments = dirPath.split('/');
        dirPathSegments.pop();
        dirPath = dirPathSegments.join('/');

        (<any>window).resolveLocalFileSystemURL(
          newUrl.nativeURL,
          function(fileEntry) {
            uploadFileDetails.path = newUrl.nativeURL;

            const file: any = getFileFromFileEntry(fileEntry);

            //log 01 
            console.log({ file });

            uploadFileDetails.size = file.size;
            uploadFileDetails.name = `${newUrl.name
              .split(':')
              .pop()}.${file.type.split('/').pop()}`;
            uploadFileDetails.type = file.type;

            async function getFileFromFileEntry(fileEntry) {

              try {
                return await new Promise((resolve, reject) =>
                  fileEntry.file(resolve, reject)
                );
              } catch (err) {
                console.log(err);
              }
            }

          },
          function(e) {
            console.error(e);
          }
        );
      });
    });

    // here uploadFileDetails is simller to what I declared at the top ;)
    // I wan't this to be populated with file properties
    // console.log(uploadFileDetails.name) --> //''

    const uploadUrl = await this.getUploadUrl(uploadFileDetails);

    const response: any = this.uploadFile(
      uploadFileDetails,
      uploadUrl
    );

    response
      .then(function(success) {
        console.log({ success });
        this.presentToast('File uploaded successfully.');
        this.loadFiles();
      })
      .catch(function(error) {
        console.log({ error });
      });
  }

即使我可以 console.log 日志 01 中的文件。我无法从 sizenametype 等文件属性中获取文件属性=15=]函数。基本上,我无法填充 uploadFileDetails 对象。我究竟做错了什么?先感谢您。

你实际上需要 4 Ionic Cordova 插件在获取文件的所有元数据后上传文件。

  1. FileChooser

    Opens the file picker on Android for the user to select a file, returns a file URI.

  2. FilePath

    This plugin allows you to resolve the native filesystem path for Android content URIs and is based on code in the aFileChooser library.

  3. File

    This plugin implements a File API allowing read/write access to files residing on the device.

  4. File Trnafer

    This plugin allows you to upload and download files.

正在获取文件的元数据。

  • file.resolveLocalFilesystemUrlfileEntry.file 为您提供所需的所有元数据, 文件名 除外。元数据中有一个名为 name 的 属性,但它始终包含值 content
  • 要获得人类可读的文件名,您需要 filePath。但请记住,您不能使用返回文件路径来检索元数据。为此,您需要来自 fileChooser 的原始 url。
  • filePathUrl.substring(filePathUrl.lastIndexOf('/') + 1) 用于仅从 filePath.
  • 获取文件名
  • 您需要 nativeURL 的文件才能上传。使用从 filePath 返回的文件路径是行不通的。
    getFileInfo(): Promise<any> {
            return this.fileChooser.open().then(fileURI => {
                return this.filePath.resolveNativePath(fileURI).then(filePathUrl => {
                    return this.file
                        .resolveLocalFilesystemUrl(fileURI)
                        .then((fileEntry: any) => {
                            return new Promise((resolve, reject) => {
                                fileEntry.file(
                                    meta =>
                                        resolve({
                                            nativeURL: fileEntry.nativeURL,
                                            fileNameFromPath: filePathUrl.substring(filePathUrl.lastIndexOf('/') + 1),
                                            ...meta,
                                        }),
                                    error => reject(error)
                                );
                            });
                        });
                });
            });
        }

select来自手机文件系统的一个文件。

async selectAFile() {

    this.getFileInfo()
        .then(async fileMeta => {

            //get the upload 
            const uploadUrl = await this.getUploadUrl(fileMeta);

            const response: Promise < any > = this.uploadFile(
                fileMeta,
                uploadUrl
            );

            response
                .then(function(success) {
                    //upload success message                       
                })
                .catch(function(error) {
                    //upload error message
                });
        })
        .catch(error => {
            //something wrong with getting file infomation
        });
}

正在上传 selected 文件。

这取决于您的后端实现。这是使用 文件传输 上传文件的方法。

uploadFile(fileMeta, uploadUrl) {

    const options: FileUploadOptions = {
      fileKey: 'file',
      fileName: fileMeta.fileNameFromPath,
      headers: {
        'Content-Length': fileMeta.size,
        'Content-Type': fileMeta.type,
      },
      httpMethod: 'PUT',
      mimeType: fileMeta.type,
    };

    const fileTransfer: FileTransferObject = this.transfer.create();
    return fileTransfer.upload(file.path, uploadUrl, options);
  }

希望对您有所帮助。 :)