バックエンドで生成された Zip ファイルの問題を一度思い出してください。
序文
プロジェクト立ち上げ前夜に、データエクスポートインターフェースを一時的に追加しました 圧縮パッケージをエクスポートすることが要件でした プロジェクトで通常使用されているダウンロードインターフェースを変更対象として選択しましたが、ファイル生成機能にファイル圧縮機能が追加されました。
問題が発生しました
ただし、他の場所で通常どおりダウンロードしたインターフェイスでは、ダウンロードした圧縮パッケージを開くことができず、
压缩包损坏
生成不可预料的压缩文件末端
された圧縮パッケージは205kb
、ダウンロード後、370kb
トラブルシューティング
Baiduと向き合うことで、 、 、などいくつかの答えが得られ流没关好
まし写入使用了字节数组导致多写入空字节
た流没有flush
。
1. 流れが正しく閉じられていない
1. プログラムの出力ストリームが閉じられているかどうかを確認する
2. ストリームを閉じる順序が正しいかどうか
しかし、私のストリームはtry-with-resource
メソッドを使用しているため、操作ストリームを閉じる必要はありません。
try (
// 1.读取要下载的内容
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
// 将要下载的文件内容通过输出流写到浏览器
ServletOutputStream outputStream = response.getOutputStream()) {
//do something
} catch (IOException e) {
e.printStackTrace();
}
拡張子:このメソッドを使用しない場合
try-with-resource
、この記事を読むと、Java で作成された zip がフローの問題で開けなかったり
、予期せぬ圧縮ファイルを開いて表示したりすることを回避できます (https://blog.csdn.net/freedom_zzc) /記事/詳細/118930027 )
2. 空白バイトが書き込まれる
ストリーム経由で書き込むときに書き込み方法が間違っていると、最後の書き込み中に null バイトがファイルに書き込まれ、ファイルを開けなくなります。間違った書き込み方法
:
不能直接用output.write(buffer)
。そうしないと、最終ストリームがバッファを完全に満たさない場合、実際よりも多くのバイトが書き込まれることになります。
byte[] b = new byte[2048];
int len;
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b);
}
正しいスペル:
byte[] b = new byte[2048];
int len;
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
3、フラッシュなし
フラッシュ ストリームがない場合、データはまだ存在しており文件缓冲区
、データは実際には書き込まれていない物理介质
ため、サービスがハングするとファイルは失われます。
ただし、内部 close メソッドを直接呼び出すと、内部フラッシュ メソッドが最初に呼び出されます。
実際、ツール クラスのコピーを直接使用して上記の問題を回避でき、コードはより簡潔になります。
hutool包中工具类
IoUtil.copy(inputStream, outputStream);
したがって、私の問題はストリームとは何の関係もありません
この時点で問題は行き詰まりました
ポジショニングリンク
問題のどの部分が変更されているかを確認するためにトラブルシューティングを行うことにしました
1. 世代
サーバー上のプログラムによって生成された圧縮パッケージをローカルに手動でダウンロードし、それを開いて問題がないことを確認し、エラーが報告されないことを確認し、続行します生成环节
。
2. SwaggerUI と PostMan を介してダウンロードする
ツールを通じてダウンロードしたところ、ファイル サイズは正常で、正常に開くことができ、エラーは報告されず、下载接口
問題がないことがわかりました。
3. 結論
現時点では、問題はフォアグラウンド呼び出しで発生していると判断でき、圧縮パッケージのダウンロードの問題は、フロントエンド呼び出しインターフェイスを変更することで解決されます。
解決
最後の解決策は、フォアグラウンド呼び出しインターフェイスにresponseType: ‘blob‘
パラメータを追加することです
。コード例は次のとおりです。
方法
最初の方法が間違っていました。バックエンドのコードを直接変更すべきではありません。経験主義は人を殺します。ファイルの書き込みに問題があると常々考えています (以前 Word をダウンロードしたときにも同様の問題が発生しました)。まずリンクを見つけてから問題を解決する必要があります。
- まず Postman を使用してファイルをダウンロードまたはエクスポートします。ファイルを開けない場合は、バックエンド コード内で問題を探します。そうでない場合は、フロントエンドの呼び出しを見つけます。
- サーバー上のローカル ファイルを開けない場合は、生成されたコード内で問題を探します。そうでない場合は、ダウンロード インターフェイスを見つけます。