4

サーブレットと Apache Commons FileUpload を使用して、設定されたディレクトリにファイルをアップロードする Java コードがあります。文字データ (テキスト ファイルなど) では問題なく動作しますが、画像ファイルは文字化けして出力されます。それらを開くことはできますが、画像が本来のように見えません。これが私のコードです:

サーブレット

protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    try {
      String customerPath = "\\leetest\\";

      // Check that we have a file upload request
      boolean isMultipart = ServletFileUpload.isMultipartContent(request);

      if (isMultipart) {
        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload();

        // Parse the request
        FileItemIterator iter = upload.getItemIterator(request);
        while (iter.hasNext()) {
          FileItemStream item = iter.next();
          String name = item.getFieldName();
          if (item.isFormField()) {
            // Form field.  Ignore for now
          } else {
            BufferedInputStream stream = new BufferedInputStream(item
                .openStream());
            if (stream == null) {
              LOGGER
                  .error("Something went wrong with fetching the stream for field "
                      + name);
            }

            byte[] bytes = StreamUtils.getBytes(stream);
            FileManager.createFile(customerPath, item.getName(), bytes);

            stream.close();
          }
        }
      }
    } catch (Exception e) {
      throw new UploadException("An error occured during upload: "
          + e.getMessage());
    }
}

StreamUtils.getBytes(ストリーム) は次のようになります。

public static byte[] getBytes(InputStream src, int buffsize)
      throws IOException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    byte[] buff = new byte[buffsize];
    while (true) {
      int nBytesRead = src.read(buff);
      if (nBytesRead < 0) {
        break;
      }
      byteStream.write(buff);
    }

    byte[] result = byteStream.toByteArray();
    byteStream.close();

    return result;
}

最後に FileManager.createFile は次のようになります。

public static void createFile(String customerPath, String filename,
      byte[] fileData) throws IOException {
    customerPath = getFullPath(customerPath + filename);
    File newFile = new File(customerPath);
    if (!newFile.getParentFile().exists()) {
      newFile.getParentFile().mkdirs();
    }

    FileOutputStream outputStream = new FileOutputStream(newFile);
    outputStream.write(fileData);
    outputStream.close();
  }

誰かが私が間違っていることを見つけることができますか?

乾杯、リー

4

5 に答える 5

4

私が気に入らない点の 1 つは、StreamUtils.getBytes() からのこのブロックにあります。

 1 while (true) {
 2   int nBytesRead = src.read(buff);
 3   if (nBytesRead < 0) {
 4     break;
 5   }
 6   byteStream.write(buff);
 7 }

6 行目では、読み込まれたバイト数に関係なく、バッファー全体を書き込みます。これが常に当てはまるとは思いません。次のようにするとより正確になります。

 1 while (true) {
 2   int nBytesRead = src.read(buff);
 3   if (nBytesRead < 0) {
 4     break;
 5   } else {
 6     byteStream.write(buff, 0, nBytesRead);
 7   }
 8 }

5 行目の 'else' と、6 行目の 2 つの追加パラメーター (配列インデックスの開始位置とコピーする長さ) に注意してください。

画像などの大きなファイルの場合、バッファーがいっぱいになる前にバッファーが返されることを想像できます (おそらく、さらに待機しています)。つまり、バッファの末尾に残っていた古いデータを意図せずに書き込んでしまうことになります。バッファが 1 バイトを超えると仮定すると、これはほぼ確実に EoF で発生していますが、EoF での余分なデータはおそらく破損の原因ではありません...それは望ましくありません。

于 2008-09-03T17:49:35.350 に答える
1

commons ioを使用するだけです。次に、IOUtils.copy(InputStream、OutputStream);を実行できます。

他にも便利なユーティリティメソッドがたくさんあります。

于 2008-09-03T20:13:20.123 に答える
0

どのような違いがあるのか​​わかりませんが、メソッドシグネチャの不一致があるようです。getBytes()メソッドで呼び出されるメソッドdoPost()には、引数が1つだけあります。

byte[] bytes = StreamUtils.getBytes(stream);

含めたメソッドソースには2つの引数があります。

public static byte[] getBytes(InputStream src, int buffsize)

お役に立てば幸いです。

于 2008-09-03T14:12:29.397 に答える
0

元のファイルとアップロードされたファイルに対してチェックサムを実行して、すぐに違いがあるかどうかを確認できますか?

ある場合は、diffの実行を調べて、変更されていないファイルの正確な部分を特定できます。

頭に浮かぶのは、ストリームの開始または終了、またはエンディアンです。

于 2008-09-03T14:13:46.553 に答える
0

画像が文字化けしていないか、途中でいくつかのパケットをドロップしていないことを確信していますか.

于 2008-09-03T13:45:49.883 に答える