matlab 通过Django REST框架发送.mat文件

mwkjh3gx  于 2022-11-15  发布在  Matlab
关注(0)|答案(1)|浏览(197)

我无法将.mat文件的内容发送到我的前端。我的最终目标是让客户只需点击一个按钮就可以下载这个.mat文件的内容,这样他们就可以拥有相同的文件了。我使用的是Next.js+Django REST框架。
我的第一次尝试如下:

class Download(APIView):
     
    def get(self, request):
          with open('file_path.mat', 'rb') as FID:
               fileInstance = FID.read()

          return Response(
              fileInstance,
              status=200,
              content_type="application/octet-stream",
          )

如果我打印出fileInstance元素,我会得到一些二进制结果:
Z\xe1\xfe\xc6\xc6\xd2\x1e_\xda~\xda|\xbf\xb6\x10_\x84\xb5~\xfe\x98\x1e\xdc\x0f\x1a\xee\xe7Y\x9e\xb5\xf5\x83\x9cS\xb3\xb5\xd4\xb7~XK\xaa\xe3\x9c\xed\x07v\xf59Kbn(\x91\x0e\xdb\xbb\xe8\xf5\xc3\xaa\x94Q\x9euQ\x1fx\x08\xf7\x15\x17\xac\xf4\x82\x19\x8e\xc9...
但我不能把它发回我的前台,因为
“UnicodeDecodeError:‘utf-8’编解码器无法解码位置137中的字节0x9c:开始字节无效”
无论我在响应中尝试发送哪个.mat文件,此错误总是相同的。
接下来,我尝试使用scipy.io.loadmat()方法。在本例中,fileInstance为我提供了一个可读性更强的字典对象,但我仍然无法将其传输到前端,因为我的dict中存在NaN:
ValueError:超出范围的浮点值不符合JSON
最后,有人建议使用h5py发回数据,如下所示:

with h5py.File('file_path.mat', 'r') as fileInstance:
     print(fileInstance)

但在这种情况下,我得到的错误是
无法打开文件(未找到文件签名)
我知道我的文件没有损坏,因为我可以在MatLab中打开它们,没有任何问题。
面对所有这些麻烦,我想知道我是否使用了正确的方法来解决这个问题。从技术上讲,我可以将通过‘scipy.io.loadmat()’获得的词典作为str元素发送,而不是二进制,但我必须想出一种方法,在一个Java脚本函数中将这个文本转换回二进制。对于我应该如何进行,有谁有什么想法吗?

wa7juj8i

wa7juj8i1#

毕竟,问题出在我的前台。不过,以下是正确的做法:

class Download(APIView):
    parser_classes = [FormParser, MultiPartParser]
    def get(self, request):
        try:
            file_path = "xyz.mat"
            response = FileResponse(file_path.open("rb"), content_type="application/octet-stream")
            response["Content-Disposition"] = f"attachment; filename=file_name"
            return response

        except Exception as e:
            return Response(status=500)

这应该会以正确的格式将正确的文件发送到前端。不需要担心编码之类的问题。
同时,在前端,您应该会收到如下文件:

onClick={() => {
          const url = '/url_to_your_api/';
          axios({ method: 'get', url: url, responseType: 'blob' })
            .then((response) => {
              const { data } = response;
              const fileName = 'file_name';
              const blob = new Blob([data], { type: 'application/octet-stream' });
              const href = URL.createObjectURL(blob);
              const link = document.createElement('a');
              link.href = href;
              link.download = fileName + '.mat';
              document.body.appendChild(link);
              link.click();
              document.body.removeChild(link);
              URL.revokeObjectURL(href);
            })
            .catch((response) => {
              console.error(response);
            });
        }}

长话短说,我遗漏的部分是指定在‘onClick()’函数中以BLOB形式接收数据。默认情况下,Axios中的响应类型设置为Json/字符串。出于这个原因,我的文件在接收时被修改,之后将不能在MatLab中使用。如果您将来遇到类似的问题,请尝试使用‘shasum’Bash函数来观察文件的散列值。正是在该函数的帮助下,我可以推断我的API函数将返回正确的值,因此问题发生在前端。

相关问题