0

ポスト ヘッダー InputStream を取得するソケットを使用して Java で http Web サーバーを開発しています。次に、ヘッダー 'boundary' と '\r\n' で分割された文字列でヘッダーを処理し、すべてのヘッダー、HashMap の Cookie を取得しました。ファイルの内容を文字列で取得し、その文字列をサーバー上のファイルに保存しました。サーバーにテキスト ファイルまたは Java ソース ファイルをアップロードすると正常に動作しますが、doc、pdf、および画像の場合、破損したファイルと破損した画像が表示されます。

    PrintWriter out;
        try {
            out = new PrintWriter(new OutputStreamWriter(
                    new FileOutputStream(UploadPath + "\\" + FileName)));
            out.print(FileData);
            out.close();
        } catch (Exception e) {

        }

上記のコードは、「FileData」の内容を「FileName」で「UploadPath」に保存します。

jpgまたはdocファイルの場合、String FileDataには、上記のコードで保存されたアップロードされたファイルのバイナリコンテンツが含まれており、両方のファイルのサイズをバイト単位でチェックし、両方のサイズがバイト単位で同じであり、実際のコンテンツの内容も一致させましたアプリケーションをデバッグして、ファイルとコンテンツの FileData 文字列を削除します。

実際にアップロードされた画像ファイルと FileData 文字列も確認しましたが、どちらもバイトごとに一致しますが、アップロードされた画像は完全に破損しています。

この丸一日をインターネットで検索した後、これに対する解決策を見つけることができません。助けてください。

ほとんどのページで提案されている apache commons を使用したくありません。

もっとコードを見たい場合は、投稿します。

4

4 に答える 4

0

次のようなバイト配列を使用して読み取ることができます

InputStream is = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();

int nRead;
byte[] data = new byte[16384];

while ((nRead = is.read(data, 0, data.length)) != -1) {
  buffer.write(data, 0, nRead);
}

buffer.flush();

return buffer.toByteArray();
于 2013-06-09T12:31:18.723 に答える
0

私はこのように私の問題を解決しました、

    while (inputRequest.available()>0) {
            try {
                int t = inputRequest.read();
                ch = (char) t;
                //here i checked each byte data
            } catch (IOException e) {
            }
    }

問題は、入力ストリームに、ストリーム内の任意の場所にあるファイル コンテンツと共に http ヘッダー フィールドが含まれていたことでした。そのため、最初に、ストリーム内に '\r' と '\n' を取得するまで、バイトを一時文字列に格納しました。このようにして、multipart/form-data HTTP ヘッダーの境界を取得し、境界とその他の既知のヘッダー コンテンツが見つかるまで一時文字列を比較してから、入力ストリームをファイル出力ストリームに送信しました。ただし、場合によっては、ヘッダーにファイル コンテンツの後に他のコンテンツが含まれている可能性があるため、間違いなく終了境界があるため、読み取った各バイトを継続的に追跡し、各バイトをファイル出力ストリームに個別に送信しました。サンプルの http ヘッダーは次のとおりです。

   Host: localhost
   User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
   Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
   Accept-Language: en-US,en;q=0.5
   Accept-Encoding: gzip, deflate
   DNT: 1
   Referer: http://localhost/index.html
   Connection: keep-alive
   Content-Type: multipart/form-data; boundary=---------------------------274761981030199
   Content-Length: 1405

   -----------------------------274761981030199
   Content-Disposition: form-data; name="name1"

   pppppp
   -----------------------------274761981030199
   Content-Disposition: form-data; name="name2"

   rrrrrrrrr
   -----------------------------274761981030199
   Content-Disposition: form-data; name="name3"

   eeeeeeee
   -----------------------------274761981030199
   Content-Disposition: form-data; name="name4"

   2
   -----------------------------274761981030199
   Content-Disposition: form-data; name="name5"; filename="CgiPost.java"
   Content-Type: text/x-java-source

   import java.io.*;

   // This appears in Core Web Programming from
   // Prentice Hall Publishers, and may be freely used
   // or adapted. 1997 Marty Hall, hall@apl.jhu.edu.


   public class CgiPost extends CgiGet 
   {

   public static void main(String[] args) 
   {

   try 
   {

   DataInputStream in
    = new DataInputStream(System.in);

   String[] data = { in.readLine() };

   CgiPost app = new CgiPost("CgiPost", data, "POST");

   app.printFile();
       } catch(IOException ioe) {
         System.out.println
           ("IOException reading POST data: " + ioe);

   }
     }

     public CgiPost(String name, String[] args,
     String type) {
       super(name, args, type);
     }
   }

   -----------------------------274761981030199
   Content-Disposition: form-data; name="name6"

   pppppppppp
   -----------------------------274761981030199--

注: 場合によっては、アプリケーション コードが inputRequest.available() に到達しても、ブラウザーがまだ要求を送信していない可能性があります。この場合、inputRequest.available() は常に 0 を返し、while ループはすぐに終了します。これを回避するには、最初に inputRequest.read() を使用して 1 バイトを読み取り、次にコードを実行します。これは、http ヘッダーの場合、他のバイトから最初のバイトを推測できるためです。

count int を使用している場合は、int の代わりに long を使用します。これは、int 変数が制限に達するとストリームが停止する場合があるためです。

int t = inputRequest.read() から返された int 値を fileoutputstream.write(t) に転送してみてください。

inputRequest.available() は、バイト形式の入力ストリームを読み取るにつれて減少し続け、ストリームで使用可能なバイト数を返します。

このようにして、大きなサイズのファイルを破損することなくアップロードできます。

これについてさらに詳細が必要な場合は、コメントを残してください。

于 2013-06-11T10:05:32.140 に答える