Java InputStream의 콘텐츠를 OutputStream에 쉽게 쓰는 방법
오늘 깜짝 놀랐어요.그동안의 내용을 간단하게 쓸 수 있는 방법을 찾을 수 없었습니다.InputStream에 대해서OutputStream자바어.물론 바이트 버퍼 코드는 쓰기 어렵지 않지만, 내 삶을 더 쉽게 만들 수 있는 무언가를 놓치고 있는 것 같습니다(그리고 코드도 더 선명합니다).
그러니까,InputStream in그리고OutputStream out, 다음과 같이 간단하게 쓸 수 있는 방법이 있습니까?
byte[] buffer = new byte[1024];
int len = in.read(buffer);
while (len != -1) {
out.write(buffer, 0, len);
len = in.read(buffer);
}
WMR이 말했듯이org.apache.commons.io.IOUtilsApache의 수법이 있습니다.그것은 당신이 찾고 있는 것과 정확히 일치합니다.
다음과 같은 것이 있습니다.
InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();
당신의 암호로.
당신이 피해가는 이유가 있나요?IOUtils?
Java 7을 사용하는 경우 표준 라이브러리의 파일(Files)이 최선의 방법입니다.
/* You can get Path from file also: file.toPath() */
Files.copy(InputStream in, Path target)
Files.copy(Path source, OutputStream out)
편집: 물론 파일에서 InputStream 또는 OutputStream 중 하나를 작성할 때 유용합니다.사용하다file.toPath()파일에서 경로를 가져옵니다.
기존 파일(예: 로 작성된 파일)에 쓰려면File.createTempFile()) 。를 통과해야 합니다.REPLACE_EXISTING복사 옵션(복사)FileAlreadyExistsException투척됩니다).
Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING)
자바 9
Java 9 이후InputStream라고 하는 메서드를 제공합니다.transferTo다음 시그니처를 사용합니다.
public long transferTo(OutputStream out) throws IOException
서류에 나와 있듯이transferTo의 내용:
이 입력 스트림에서 모든 바이트를 읽고 읽기 순서대로 지정된 출력 스트림에 바이트를 씁니다.반환되는 경우 이 입력 스트림은 스트림의 끝에 있습니다.이 메서드는 어느 스트림도 닫히지 않습니다.
이 메서드는 입력 스트림에서 읽거나 출력 스트림에 쓰는 것을 무기한 차단할 수 있습니다.입력 및/또는 출력 스트림이 비동기적으로 닫히거나 전송 중에 스레드가 중단된 경우 동작은 입력 및 출력 스트림에 따라 매우 다르므로 지정되지 않습니다.
그래서 자바 콘텐츠를 작성하기 위해서InputStream에 대해서OutputStream, 다음과 같이 쓸 수 있습니다.
input.transferTo(output);
이거면 될 것 같은데 꼭 테스트...사소한 '개선'도 있지만 읽기 쉽기 때문에 비용이 많이 들 수 있습니다.
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
Guava 사용:
ByteStreams.copy(inputStream, outputStream);
심플한 기능
이 명령어가 필요한 경우에만InputStream에 대해서File다음 간단한 기능을 사용할 수 있습니다.
private void copyInputStreamToFile( InputStream in, File file ) {
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
그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;
}
Spring 프레임워크를 사용하는 사용자에게 유용한 Stream Utils 클래스가 있습니다.
StreamUtils.copy(in, out);
위의 경우 스트림이 닫히지 않습니다.복사 후 스트림을 닫으려면 FileCopyUtils 클래스를 대신 사용합니다.
FileCopyUtils.copy(in, out);
PipedInputStream ★★★★★★★★★★★★★★★★★」PipedOutputStream는 Javadoc에서 설명한 바와 같이 여러 스레드가 있는 경우에만 사용해야 합니다.
입력 은 스레드 을 ""로.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를 사용하여 대량의 데이터를 복사하거나 스트림에서 장시간 정지된 데이터를 복사할 경우 유용합니다.
JDK 방식으로는 이 작업을 쉽게 수행할 수 없지만 Apocalisp가 이미 언급했듯이 이 아이디어를 가진 사람은 당신뿐만이 아닙니다.자카르타 Commons IO에서 IOUtils를 사용할 수 있습니다.IMO가 JDK의 일부여야 하는 기타 유용한 기능도 많이 있습니다.
Java7 및 리소스 사용 시 간결하고 읽기 쉬운 버전이 제공됩니다.
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();
}
가장 간단한 for loop을 사용하는 방법을 소개합니다.
private void copy(final InputStream in, final OutputStream out)
throws IOException {
final byte[] b = new byte[8192];
for (int r; (r = in.read(b)) != -1;) {
out.write(b, 0, r);
}
}
Commons Net의 Util 클래스 사용:
import org.apache.commons.net.io.Util;
...
Util.copyStream(in, out);
용 i i i i를 쓴다.BufferedInputStream ★★★★★★★★★★★★★★★★★」BufferedOutputStream에서
try (OutputStream out = new BufferedOutputStream(...);
InputStream in = new BufferedInputStream(...))) {
int ch;
while ((ch = in.read()) != -1) {
out.write(ch);
}
}
IMHO 보다 최소화된 스니펫(길이 변수 범위도 좁음):
byte[] buffer = new byte[2048];
for (int n = in.read(buffer); n >= 0; n = in.read(buffer))
out.write(buffer, 0, n);
왜 더 많은 더 많이 수 .for루 loop loop loop loop loop loop loop loop 。while"불량한" 스타일로 간주되는 할당 및 테스트 표현과 함께.
대부분의 파일이 1024바이트보다 크기 때문에 큰 버퍼를 사용하는 것이 좋다고 생각합니다.또한 읽기 바이트 수가 양수인지 확인하는 것이 좋습니다.
byte[] buffer = new byte[4096];
int n;
while ((n = in.read(buffer)) > 0) {
out.write(buffer, 0, n);
}
out.close();
이게 내 최선이야!!
그리고 너무 일반적이기 때문에 사용하지 마세요.버퍼 메모리를 제어하면 코드 성능이 향상됩니다.
public static void transfer(InputStream in, OutputStream out, int buffer) throws IOException {
byte[] read = new byte[buffer]; // Your buffer size.
while (0 < (buffer = in.read(read)))
out.write(read, 0, buffer);
}
스트림의 크기를 미리 알고 있을 때 이 (개선 가능한) 방법으로 사용하고 있습니다.
public static void transfer(int size, InputStream in, OutputStream out) throws IOException {
transfer(in, out,
size > 0xFFFF ? 0xFFFF // 16bits 65,536
: size > 0xFFF ? 0xFFF// 12bits 4096
: size < 0xFF ? 0xFF // 8bits 256
: size
);
}
읽기 쉽지는 않지만 효과적이며 의존성이 없으며 Java 버전에서도 실행 가능
byte[] buffer=new byte[1024];
for(int n; (n=inputStream.read(buffer))!=-1; outputStream.write(buffer,0,n));
PipedInputStream과 PipedOutputStream은 서로 연결할 수 있으므로 도움이 될 수 있습니다.
다른 후보로는 Guava I/O 유틸리티가 있습니다.
http://code.google.com/p/guava-libraries/wiki/IOExplained
Guava는 이미 내 프로젝트에서 매우 유용하기 때문에 한 가지 기능을 위해 다른 라이브러리를 추가하는 것보다 이것들을 사용해야겠다고 생각했습니다.
하였습니다.ByteStreamKt.copyTo(src, dst, buffer.length)
여기 제 코드가 있습니다.
public static void replaceCurrentDb(Context context, Uri newDbUri) {
try {
File currentDb = context.getDatabasePath(DATABASE_NAME);
if (currentDb.exists()) {
InputStream src = context.getContentResolver().openInputStream(newDbUri);
FileOutputStream dst = new FileOutputStream(currentDb);
final byte[] buffer = new byte[8 * 1024];
ByteStreamsKt.copyTo(src, dst, buffer.length);
src.close();
dst.close();
Toast.makeText(context, "SUCCESS! Your selected file is set as current menu.", Toast.LENGTH_LONG).show();
}
else
Log.e("DOWNLOAD:::: Database", " fail, database not found");
}
catch (IOException e) {
Toast.makeText(context, "Data Download FAIL.", Toast.LENGTH_LONG).show();
Log.e("DOWNLOAD FAIL!!!", "fail, reason:", e);
}
}
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;
}
선인장 체험:
new LengthOf(new TeeInput(input, output)).value();
상세한 것에 대하여는, http://www.yegor256.com/2017/06/22/object-oriented-input-output-in-cactoos.html 를 참조해 주세요.
이 방법을 사용할 수 있습니다.
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){}
}
언급URL : https://stackoverflow.com/questions/43157/easy-way-to-write-contents-of-a-java-inputstream-to-an-outputstream
'programing' 카테고리의 다른 글
| Keystore 비밀번호 변경 (0) | 2022.07.23 |
|---|---|
| 기존 이클립스 프로젝트를 메이븐 프로젝트로 변환 (0) | 2022.07.22 |
| Java에서 "instance of" 사용 (0) | 2022.07.21 |
| 자바를 사용하여 문자열의 첫 글자를 대문자화하려면 어떻게 해야 합니까? (0) | 2022.07.21 |
| Vue 2에서 비반응 구성 요소 데이터를 설정하는 방법 (0) | 2022.07.21 |