我们从第三方API调用接收文件数据,该调用在一个变量中返回内容类型,在另一个变量中返回文件内容。文件内容是"垃圾代码。"例如:
$doc->fileContents = "A�[�j쎪A����Kb����m��= ....";
$doc->fileType = "application/msword";
我需要能够为我的用户提供一个可点击的方法来下载文件,但只是将内容写入文件并强制下载该内容类型只会打开一个包含所有垃圾的文件...而不是真实的文件内容。
编辑:根据Patrick Q的要求,我做了标准的fwrite方式:$fp = fopen($filename, 'w'); // filename is generated elsewhere
fwrite($fp, $doc->fileContents);
fclose($fp);
所以问题是,如何从这个垃圾中创建一个真实的,可用的文件?
答案 0 :(得分:0)
数据看起来像二进制文件数据。首先不需要将其写入文件,只需确保在将Content-Transfer-Encoding
标题发送到浏览器进行下载时将binary
标题设置为$doc->fileType
。
我假设您已经有了将.doc
映射到具有正确扩展名的文件名的方法,因为您的示例是application/msword
文档,所以我只是在这里硬连线// your logic here to determine the filename sent to the browser
$filename = "file.doc";
// set the minimum appropriate HTTP headers
header('Content-Type: ' . $doc->fileType);
header('Content-Length: ' . strlen($doc->fileContents));
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary'); // this is an important one
// send the file and stop
echo $doc->fileContents;
exit;
。
$fp = fopen($filename, 'wb');
fwrite($fp, $doc->fileContents);
fclose($fp);
如果 首先将其写入文件,请确保以二进制模式打开它:
public View getTabView(Context context, int position) {
int[] unreadCount = {3, 1, 2};
View tab = LayoutInflater.from(context).inflate(R.layout.partial_custom_tab, null);
tabText = (TextView) tab.findViewById(R.id.tab_title);
counter = (View) tab.findViewById(R.id.tab_badge);
tabText.setText(mPages.get(position).title);
if (mPages.get(position).icon != null) {
counter.setVisibility(View.VISIBLE);
counter.setBackground(mPages.get(position).icon);
} else {
counter.setVisibility(View.GONE);
}
BadgeDrawable badge = new BadgeDrawable(getContext(),
getResources().getColor(R.color.colorAccent));
if (unreadCount[position] > 0) {
counter.setVisibility(View.VISIBLE);
badge.setCount(unreadCount[position]);
badge.mutate();
counter.setBackground(badge);
} else {
counter.setVisibility(View.GONE);
}
if (position == 0) {
tab.setSelected(true);
}
return tab;
}