Erinnern Sie sich einmal an das Problem mit der im Backend generierten Zip-Datei
Vorwort
Am Vorabend des Projektstarts wurde vorübergehend eine Datenexportschnittstelle hinzugefügt. Die Anforderung bestand darin, das komprimierte Paket zu exportieren. Die normalerweise im Projekt verwendete Download-Schnittstelle wurde zur Änderung ausgewählt, aber die Dateikomprimierungsfunktion wurde zur Dateigenerierungsfunktion hinzugefügt .
Es gab ein Problem
In der Schnittstelle, die normalerweise an anderen Orten heruntergeladen wird, kann das heruntergeladene komprimierte Paket jedoch nicht geöffnet werden, und es wird die Meldung angezeigt
压缩包损坏
,不可预料的压缩文件末端
dass das generierte komprimierte Paket vorhanden ist205kb
. Nach dem Herunterladen ist dies der Fall370kb
Fehlerbehebung
Als ich mich Baidu stellte, erhielt ich mehrere Antworten 流没关好
usw.写入使用了字节数组导致多写入空字节
流没有flush
1. Der Durchfluss ist nicht richtig geschlossen
1. Überprüfen Sie, ob der Ausgabestream des Programms geschlossen ist.
2. Ob die Reihenfolge zum Schließen des Streams korrekt ist.
Mein Stream verwendet jedoch try-with-resource
eine Methode und es besteht keine Notwendigkeit, den Operationsstream zu schließen.
try (
// 1.读取要下载的内容
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
// 将要下载的文件内容通过输出流写到浏览器
ServletOutputStream outputStream = response.getOutputStream()) {
//do something
} catch (IOException e) {
e.printStackTrace();
}
Erweiterung: Wenn Sie die Methode nicht verwenden
try-with-resource
, können Sie diesen Artikel lesen, um zu vermeiden, dass die von Java erstellte ZIP-Datei aufgrund von Flussproblemen nicht geöffnet werden kann
oder unvorhersehbare komprimierte Dateien geöffnet und angezeigt werden (https://blog.csdn.net/freedom_zzc /article/details/118930027 )
2. Leerbytes werden geschrieben
Wenn beim Schreiben durch den Stream die Schreibmethode falsch ist, wird beim letzten Schreibvorgang ein Nullbyte in die Datei geschrieben, was dazu führt, dass die Datei nicht geöffnet werden kann. Die
falsche Schreibmethode:
不能直接用output.write(buffer)
. Andernfalls werden mehr Bytes geschrieben als tatsächlich, wenn der endgültige Stream den Puffer nicht vollständig füllt
byte[] b = new byte[2048];
int len;
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b);
}
Korrekte Rechtschreibung:
byte[] b = new byte[2048];
int len;
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
Drei, kein Flush
Wenn kein Flush-Stream vorhanden ist, sind die Daten noch vorhanden 文件缓冲区
und wurden nicht tatsächlich geschrieben 物理介质
. Wenn der Dienst hängt, geht die Datei verloren.
Wenn Sie jedoch die interne Close-Methode direkt aufrufen, wird zuerst die interne Flush-Methode aufgerufen
Tatsächlich können Sie die oben genannten Probleme direkt mit der Kopie der Tool-Klasse vermeiden und den Code prägnanter gestalten
hutool包中工具类
IoUtil.copy(inputStream, outputStream);
Mein Problem hat also nichts mit dem Stream zu tun
Zu diesem Zeitpunkt geriet das Thema in eine Sackgasse
Positionierungslink
Ich habe mich für eine Fehlerbehebung entschieden, um herauszufinden, welcher Teil des Problems geändert wird
1. Generation
Laden Sie das vom Programm auf dem Server generierte komprimierte Paket manuell auf den lokalen Server herunter, öffnen Sie es und stellen Sie fest, dass kein Problem vorliegt, kein Fehler gemeldet wird, stellen Sie sicher, dass kein Problem vorliegt, und fahren Sie 生成环节
fort
2. Über SwaggerUI und PostMan herunterladen
Über das Tool heruntergeladen, festgestellt, dass die Dateigröße normal ist, kann normal geöffnet werden, es wird kein Fehler gemeldet, sicher, dass 下载接口
es kein Problem gibt
3. Fazit
Derzeit kann festgestellt werden, dass das Problem beim Vordergrundaufruf auftritt und das Problem des Herunterladens des komprimierten Pakets durch Ändern der Front-End-Aufrufschnittstelle gelöst wird.
lösen
responseType: ‘blob‘
Die endgültige Lösung besteht darin, Parameter zur Vordergrundaufrufschnittstelle hinzuzufügen
. Das Codebeispiel lautet wie folgt:
Methode
Die Methode war am Anfang falsch. Sie sollten den Back-End-Code nicht direkt ändern. Empirismus tötet Menschen. Ich denke normalerweise, dass es ein Problem beim Schreiben von Dateien gibt (ein ähnliches Problem trat auf, als ich zuvor Word heruntergeladen habe). Zuerst sollte der Link gefunden und dann das Problem gelöst werden.
- Verwenden Sie zuerst Postman, um die Datei herunterzuladen oder zu exportieren. Wenn sie nicht geöffnet werden kann, suchen Sie dann im Backend-Code nach dem Problem, andernfalls suchen Sie den Frontend-Aufruf
- Wenn die lokale Datei auf dem Server nicht geöffnet werden kann, suchen Sie im generierten Code nach dem Problem, andernfalls suchen Sie die Download-Schnittstelle