InputStreamを仮想ファイルに変換する方法


82

入力変数の1つがjava.io.Fileタイプであることを期待するメソッドがありますが、取得するのはInputStreamのみです。また、メソッドのシグネチャを変更することはできません。

実際にファイルをファイルシステムに書き込まずに、InputStreamをファイルタイプに変換するにはどうすればよいですか?


これは組み込み関数ですか?それともカスタム関数ですか?
リチャードJ.ロスIII

2
@Richard:「メソッドのシグネチャを変更できません。」
BalusC 2010年

FileInputStreamの代わりにオブジェクトが必要なのはなぜですか?
ポインデクスター2010年

2
使用しているAPIがファイルを義務付けているため、InputStreamを使用できません
Ram

誰かがInputStreamsの代わりにファイルのみを受け入れる壊れたAPIを設計したようです、そして今あなたはこのAPIを使わなければなりません
Mike 7619年

回答:


123

このようなものが機能するはずです。簡単にするために、Java 7機能(閉じることができるリソースでブロックを試す)とApachecommons-ioのIOUtilsを使用したことに注意してください。それらを使用できない場合は少し長くなりますが、同じ考えです。

import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class StreamUtil {

    public static final String PREFIX = "stream2file";
    public static final String SUFFIX = ".tmp";

    public static File stream2file (InputStream in) throws IOException {
        final File tempFile = File.createTempFile(PREFIX, SUFFIX);
        tempFile.deleteOnExit();
        try (FileOutputStream out = new FileOutputStream(tempFile)) {
            IOUtils.copy(in, out);
        }
        return tempFile;
    }

}

8
createTempFileは、ファイルシステムで確認できる実際のファイルを実際に書き込みませんか?
Androidデベロッパー

あなたは技術的に正しいです。上記のコードを使用すると、一時ファイルは、プログラムが終了するか、プログラムによって削除されるまで存在します。
cobbzilla 2016

deleteOnExitのドキュメントには、動作するためにそれを信頼すべきではないと書かれています(そして、実際には何もしないと思います):developer.android.com/reference/java/io/…。あなたが任意のファイルを使用せずに、再生にオーディオをストリーミングする方法を知っていればまた、ここではそれについて書いてください:stackoverflow.com/q/36552381/878126
Androidデベロッパー

4
一般的に言って、私はアプリケーションがそうすることが理にかなっているときに一時ファイルを削除することを好みます。私deleteOnExitは追加のサニティチェックとして使用し、無条件にそれに依存することはありません。特定の状況(kill -9JVMなど)では、削除を実行するシャットダウンフックが呼び出されないことを私は知っています。
cobbzilla 2016

これをAndroidで使用している場合はimplementation 'org.apache.directory.studio:org.apache.commons.io:2.4'、gradleに追加してください。
LordParsley 2018年

30

できません。入力ストリームは単なるデータの一般的なストリームであり、実際にファイルから発信されているという保証はありません。誰かがWebサービスの読み取りからInputStreamを作成した場合、または文字列をInputStreamに変換した場合、これをファイルにリンクする方法はありません。したがって、実際に実行できるのは、ストリームから一時ファイルにデータを書き込み(たとえば、File.createTempFileメソッドを使用して)、このファイルをメソッドにフィードすることだけです。


8
確かに、それFile#createTempFile()は本当にあなたの最善の策です。
BalusC 2010年

7
も参照してくださいFile#deleteOnExit()。これにより、JVMは、JVMの終了時にファイルを自動的に削除しようとします。もちろん、ファイルが不要になり、使用されなくなったことがわかったら、一時ファイルを手動ですぐに削除することをお勧めします。しかし、不完全な世界では、不完全な解決策が必要になることがあります。
マイククラーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.