通过Django Rest Framework发送.mat文件



我在将.mat文件的内容发送到前端时遇到问题。我的最终目标是让客户只需点击一个按钮就可以下载这个.mat文件的内容,这样他们就可以拥有相同的文件。我使用Next.js+Django Rest Framework。

我的第一次尝试如下:

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\xf\xc6\xx6\xd2\xae\xda~\xda|\xbf\xb6\x10_\x84\xb5~\xf\x98\xae\xdc\x0f\xa\xee\xe7Y\x9e\xf5\x83\x9cS\xb3\xd4\xb7~XK\xaa\xe3\x9c\x07v\x59Kbn \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为我提供了一个可读性更强的dictionary对象,但由于dict:中存在NaN,我仍然无法将其传输到前端

ValueError:超出范围的浮点值不符合JSON的

最后,一些人建议使用h5py来发回数据,例如:

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

但在这种情况下,我得到的错误是

无法打开文件(找不到文件签名(

我知道我的文件没有损坏,因为我可以在Matlab中毫无问题地打开它们。

遇到这么多麻烦,我想知道我是否用了正确的方法来解决这个问题。从技术上讲,我可以将通过"scipy.io.loadmat(("获得的字典作为str元素而不是二进制元素发送,但我必须想办法在Javascript函数中将此文本转换回二进制。有人会对我该怎么做有什么想法吗?

问题毕竟在我的前端。尽管如此,以下是正确的方法:

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的responseType设置为Json/String。出于这个原因,我的文件在接收时被修改了,之后将无法在matlab中使用。如果您将来遇到类似的问题,请尝试使用"shasum"BASH函数来观察文件的哈希值。正是在这个函数的帮助下,我可以推断我的API函数将返回正确的值,因此问题发生在前端。

最新更新