0

次のような状況があります。サーブレット内でファイルを作成してから削除する必要があります。ファイルを実行すると、ファイルがまだサーバーにあることがわかったので、手動で削除しようとしましたが、できません。次のメッセージが表示されます。

このファイルは別のプログラムによって開かれています: javaw.exe

これが私のコードです:

public class GenerateFile extends Action { 
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("ok");
        String fileName = request.getParameter("fileName");
        Integer nbrParam = Integer.parseInt(request.getParameter("nbrParam"));
        String[] valueParam = new String[nbrParam+1];
        for(int i =1;i<=nbrParam;i++)
        {  System.out.println(request.getParameter("param"+i));
            valueParam[i]=request.getParameter("param"+i);
        }
        FileInputStream in = new FileInputStream("C:\\Users\\free\\Desktop\\myworkspace\\gestionRH\\WebRoot\\fiches\\"+fileName+".doc");
        POIFSFileSystem fs = new POIFSFileSystem(in);
        HWPFDocument doc = new HWPFDocument(fs);
        Range r = doc.getRange();
        for(int i=1;i<=nbrParam;i++)
        {   System.out.println("<param"+i+">");
            System.out.println(valueParam[i]);
            r.replaceText("<param"+i+">", valueParam[i]);
        }
        File  file = new File("C:\\Users\\free\\Desktop\\myworkspace\\gestionRH\\WebRoot\\fiches\\temp");
        File temp = File.createTempFile("monfile",".doc",file);
        String tempName =temp.getName();
        doc.write( new FileOutputStream(temp));
        OutputStream out = response.getOutputStream();
        response.setContentType("application/rtf");
        response.setHeader("Content-Disposition","attachment; filename=Decision");
        FileInputStream in1 = new FileInputStream(temp);
        byte[] buffer = new byte[4096];
        int length;

        while ((length = in1.read(buffer)) > 0){
            out.write(buffer, 0, length);
        }
        in1.close();
        out.flush();
        System.out.println("C:\\Users\\free\\Desktop\\myworkspace\\gestionRH\\WebRoot\\fiches\\temp\\"+tempName);
        File f = new File("C:\\Users\\free\\Desktop\\myworkspace\\gestionRH\\WebRoot\\fiches\\temp\\"+tempName);
        f.delete();

        return null;
    }
}
4

6 に答える 6

4

すべてのファイル読み取りオブジェクト インスタンスを閉じる必要があります。また、ファイルを手動で削除できる場合は、java を閉じてから削除する必要があります。javaw は、コンソール外で java を起動するプロセスです。

于 2012-09-17T10:50:28.780 に答える
2

問題はnew FileOutputStream(tempName)、そのファイルに書き込む を作成しているが、その出力ストリーム (またはそれにリンクされている別の出力ストリーム) を決して閉じないことです。

これを行う:

FileOutputStream fos = newFileOutputStream(tempName);
// use it
fos.close(); // CLOSE IT!!

// then you can delete the file

簡素化する

たぶん、一時ファイルなしで別の方法で作業を行うことができます...

例:は次のdoc.write(new FileOutputStream(tempName))ように置き換えることができます:

doc.write(response.getOutputStream());

このように、doc はそのバイトを必要な場所に直接送信します。一時ファイルに送信する必要はありません。

入力/出力ストリームの背後にある考え方は、それらを構成することです。Input/OutputStream は抽象基本クラスです。そして、多くの実装があります:

  • メモリに基づく: ByteArrayInput/OutputStream
  • ファイルに基づく: FileInputOutputStream
  • 別の出力ストリームへの圧縮/解凍: GZipInputOutputStream
  • 等々

その美しさは、デコレータ パターンを適用して機能を追加することです。例:

new GZipOutputStream(new ByteArrayOutputStream());

// creates an outputstreams that compress data received and send it to the other stream
// the BAOS then writes the received bytes to memory


new GZipOutputStream(new FileOutputStream());
// it's the same but sending compressed bytes to a file.
于 2012-09-17T10:54:45.053 に答える
1

IO機能については、コミュニティからすでに提供されているある種のjarを使用することをお勧めします。たとえば、common-io.xx.jar、spring-core.jar

    Eg, org.apache.commons.io.FileUtils;
        FileUtils.copyDirectory(from, to);
        FileUtils.deleteDirectory(childDir);
        FileUtils.forceDelete(springConfigDir);
        FileUtils.writeByteArrayToFile(file, data);

        org.springframework.util.FileSystemUtils;
        FileSystemUtils.copyRecursively(from, to);
        FileSystemUtils.deleteRecursively(dir);

幸運を!

于 2012-09-17T11:01:13.880 に答える
1

ファイルハンドラーを開くときはいつでも、それを閉じる必要があります。長期間実行するJavaアプリケーションでは、未使用のファイルハンドラーを操作し終えたら、すぐにすべて閉じることを強くお勧めします。

FileOutputStream一般的なファイルハンドラーの例はとですFileInputstream。これは、どのように開閉するかの良い例です。FileOutputStream

FileOutputStream fos = null;
try {
    fos = new FileOutputStream(tempName);
    // do something
} catch (IOException ex) {
    // deal with exceptions
} finally {
    // close if fos is not null
    if (fos != null) {
        fos.close();
    }
}

これは絶対に行わないでください。

doc.write( new FileOutputStream(temp));

ファイルハンドラーへの参照がない場合、ファイルハンドラーを閉じることはできないためです。

于 2012-09-17T11:02:45.803 に答える
1

ファイル (out) を閉じていないように見えるため、このアクションのスレッドに残り、削除を制限しています。

それが役に立てば幸い。

于 2012-09-17T10:52:43.307 に答える
1

ProcMonを試して、開いているファイルを正確に保持しているプロセスを見つける必要があるかもしれません

于 2012-09-17T10:54:03.450 に答える