まだ準備ができていないときに、ユーザーがファイルのダウンロードを開始できるようにしたい。「30秒待って、ファイルを準備しています」というページにユーザーを送りたくありません。事前にファイルを生成できません。ユーザーがフォームをクリック/送信し、ダウンロード場所を選択してダウンロードを開始する必要があります。生成されるファイルはzipになるので、zipの最初の数バイト(常に同じ)でファイル名を送信できるはずであり、ファイルが生成される前に、tcpパケットが正しく送信されたことなどを確認しないでください。それと、ファイルが生成された後、残りを送信します。
それ、どうやったら出来るの?それができるツールはありますか?それとももっと良い方法はありますか?より高レベルのソリューションの方が優れていますが、Cは私の強みではありません。できればPythonで。ありがとう。
生成されるファイルはzipであり、準備される前に送信するものはまだありません。基本的に、入力に応じて、ファイルを圧縮してユーザーに提供するよりも、ファイルのセットを生成します(数十秒かかります)。私のアプリケーションはLinux上のPythonですが、どのサーバーを使用するかはそれほど重要ではありません。
それは不可能だという主張にもかかわらず、私はなんとか方法を見つけることができました。その間にGoを少し学んだので、それを使用しましたが、他の言語でもそれほど変わらないと思います。
基本的に、最初のバイトはライターで書き込まれ、次にフラッシュされます。休憩を待つよりもブラウザ。
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
)
func Zip(w http.ResponseWriter, r *http.Request) {
file_name := r.URL.Path
file_name = strings.TrimPrefix(file_name, "/files/")
w.Header().Set("Content-type", "application/zip")
w.Write([]byte{80})
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
for {
if _, err := os.Stat("./files/" + file_name); err == nil {
fmt.Println("file found, breaking")
break
}
time.Sleep(time.Second)
}
stream_file_bytes, err := ioutil.ReadFile("./files/" + file_name)
if err != nil {
fmt.Println(err)
return
}
b := bytes.NewBuffer(stream_file_bytes)
b.Next(1)
b.WriteTo(w)
fmt.Println("end")
}
func main() {
http.HandleFunc("/files/", Zip)
if err := http.ListenAndServe(":8090", nil); err != nil {
panic(err)
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加