482

今日、Javaで anInputStreamから an への内容を書き込む簡単な方法を見つけられなかったことに驚きました。OutputStream明らかに、バイト バッファ コードを書くのは難しくありませんが、作業を楽にする (そしてコードをより明確にする) 何かが欠けているのではないかと思います。

InputStream inでは、 anと anが与えられたOutputStream out場合、次のように書く簡単な方法はありますか?

byte[] buffer = new byte[1024];
int len = in.read(buffer);
while (len != -1) {
    out.write(buffer, 0, len);
    len = in.read(buffer);
}
4

24 に答える 24

408

WMR が述べたように、org.apache.commons.io.IOUtilsfrom Apache には、copy(InputStream,OutputStream)探していることを正確に行うメソッドがあります。

だから、あなたは持っています:

InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();

...あなたのコードで。

避けている理由はありますIOUtilsか?

于 2008-09-09T12:36:43.507 に答える
221

Java 9

Java 9 以降、次のシグネチャでInputStream呼び出されるメソッドを提供します。transferTo

public long transferTo(OutputStream out) throws IOException

ドキュメントに記載されているように、次のようになりtransferToます。

この入力ストリームからすべてのバイトを読み取り、読み取った順序で指定された出力ストリームにバイトを書き込みます。戻ると、この入力ストリームはストリームの最後になります。このメソッドはどちらのストリームも閉じません。

このメソッドは、入力ストリームからの読み取り、または出力ストリームへの書き込みを無期限にブロックする場合があります。入力および/または出力ストリームが非同期に閉じられた場合、または転送中にスレッドが中断された場合の動作は、入力および出力ストリームに大きく固有であるため、指定されていません。

したがって、Java のコンテンツを に書き込むには、次のように記述InputStreamできOutputStreamます。

input.transferTo(output);
于 2016-09-11T21:44:31.193 に答える
109

これでうまくいくと思いますが、必ずテストしてください...マイナーな「改善」ですが、読みやすさが少し犠牲になる可能性があります。

byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
    out.write(buffer, 0, len);
}
于 2008-09-04T03:58:20.707 に答える
57

グアバの使用ByteStreams.copy()

ByteStreams.copy(inputStream, outputStream);
于 2014-03-26T10:12:22.107 に答える
21

JDK同じコードを使用しているため、不格好なサードパーティのライブラリがなければ「より簡単な」方法はないように思われます (いずれにせよ、おそらく何も変わらないでしょう)。以下は から直接コピーされjava.nio.file.Files.javaます:

// buffer size used for reading and writing
private static final int BUFFER_SIZE = 8192;

/**
  * Reads all bytes from an input stream and writes them to an output stream.
  */
private static long copy(InputStream source, OutputStream sink) throws IOException {
    long nread = 0L;
    byte[] buf = new byte[BUFFER_SIZE];
    int n;
    while ((n = source.read(buf)) > 0) {
        sink.write(buf, 0, n);
        nread += n;
    }
    return nread;
}
于 2016-10-13T11:10:11.450 に答える
18

PipedInputStreamJavadoc に記載されているようにPipedOutputStream、複数のスレッドがある場合にのみ使用する必要があります。

また、入力ストリームと出力ストリームは、スレッドの割り込みを s でラップしないことに注意してくださいIOException。したがって、コードに割り込みポリシーを組み込むことを検討する必要があります。

byte[] buffer = new byte[1024];
int len = in.read(buffer);
while (len != -1) {
    out.write(buffer, 0, len);
    len = in.read(buffer);
    if (Thread.interrupted()) {
        throw new InterruptedException();
    }
}

これは、この API を使用して大量のデータをコピーしたり、ストリームからのデータが耐えられないほど長時間スタックしたりする場合に便利です。

于 2009-02-12T10:37:28.557 に答える
8

JDKメソッドでこれをはるかに簡単にする方法はありませんが、Apocalispがすでに述べたように、このアイデアを持っているのはあなただけではありません。JakartaCommons IOのIOUtilsを使用できます。また、他にも多くの便利な機能があります。 IMOは実際にはJDKの一部である必要があります...

于 2008-09-04T10:50:10.450 に答える
7

Java7 とtry-with-resourcesを使用すると、簡略化された読みやすいバージョンが付属しています。

try(InputStream inputStream = new FileInputStream("C:\\mov.mp4");
    OutputStream outputStream = new FileOutputStream("D:\\mov.mp4")) {

    byte[] buffer = new byte[10*1024];

    for (int length; (length = inputStream.read(buffer)) != -1; ) {
        outputStream.write(buffer, 0, length);
    }
} catch (FileNotFoundException exception) {
    exception.printStackTrace();
} catch (IOException ioException) {
    ioException.printStackTrace();
}
于 2015-08-21T08:52:19.760 に答える
3

私見のより最小限のスニペット(長さ変数の範囲もより狭くなります):

byte[] buffer = new byte[2048];
for (int n = in.read(buffer); n >= 0; n = in.read(buffer))
    out.write(buffer, 0, n);

for余談ですが、ループを使用せずwhileに代入とテストの式を使用する人が増えている理由がわかりません。

于 2015-12-10T00:29:32.200 に答える
0

もう 1 つの候補は、Guava I/O ユーティリティです。

http://code.google.com/p/guava-libraries/wiki/IOExplained

Guava は私のプロジェクトですでに非常に有用であるため、1 つの関数に別のライブラリを追加するのではなく、これらを使用すると考えました。

于 2012-12-11T05:42:34.057 に答える
0

PipedInputStream と PipedOutputStream は、相互に接続できるため、ある程度役立つ場合があります。

于 2008-09-04T04:04:07.480 に答える
-1
public static boolean copyFile(InputStream inputStream, OutputStream out) {
    byte buf[] = new byte[1024];
    int len;
    long startTime=System.currentTimeMillis();

    try {
        while ((len = inputStream.read(buf)) != -1) {
            out.write(buf, 0, len);
        }

        long endTime=System.currentTimeMillis()-startTime;
        Log.v("","Time taken to transfer all bytes is : "+endTime);
        out.close();
        inputStream.close();

    } catch (IOException e) {

        return false;
    }
    return true;
}
于 2015-04-02T18:48:24.763 に答える
-6

この方法を使用できます

public static void copyStream(InputStream is, OutputStream os)
 {
     final int buffer_size=1024;
     try
     {
         byte[] bytes=new byte[buffer_size];
         for(;;)
         {
           int count=is.read(bytes, 0, buffer_size);
           if(count==-1)
               break;
           os.write(bytes, 0, count);
         }
     }
     catch(Exception ex){}
 }
于 2014-03-06T11:23:20.440 に答える