문제

나는 그냥 재생 Java 파일 시스템은 API,그리고 아래로 다음과 같은 기능을 사용하는 복사본을 바이너리 파일이 있습니다.원래의 소유자가 웹에서 그러나 나에 추가하려고/catch/마지막으로 절을 확인하는 뭔가 잘못된 발생,버퍼를 스트림이 있습니다(그래서,내 OS 자원을 해제)하기 전에 휴대 전화 나 태블릿의 기능입니다.

내가 다듬어 기능하는 패턴을 보여줍:

public static void copyFile(FileOutputStream oDStream, FileInputStream oSStream) throw etc...
{
   BufferedInputStream oSBuffer = new BufferedInputStream(oSStream, 4096);
   BufferedOutputStream oDBuffer = new BufferedOutputStream(oDStream, 4096);

   try
   { 
      try
      { 
         int c;

         while((c = oSBuffer.read()) != -1)  // could throw a IOException
         {
            oDBuffer.write(c);  // could throw a IOException
         }
      }
      finally
      {
         oDBuffer.close(); // could throw a IOException
      }
   }
   finally
   {
      oSBuffer.close(); // could throw a IOException
   }
}

지금까지 내가 이해할 수는 없을 넣어 두 close() 에서 마지막으로 절기 때문에 첫 번째 close() 수 잘 던져,그 후,두 번째 것이 아니라 실행할 수 있습니다.

알 C#가 패턴을 처리했을 것이와이 using 키워드입니다.

나는 심지어 잘 알고 있는 C++코드었을 것 같은 것(사용한 자바와 같은 API):

void copyFile(FileOutputStream & oDStream, FileInputStream & oSStream)
{
   BufferedInputStream oSBuffer(oSStream, 4096);
   BufferedOutputStream oDBuffer(oDStream, 4096);

   int c;

   while((c = oSBuffer.read()) != -1)  // could throw a IOException
   {
      oDBuffer.write(c);  // could throw a IOException
   }

   // I don't care about resources, as RAII handle them for me
}

나는 뭔가가 또는 정말을 생산하는 추하고 부풀어 코드에서는 자바를 핸들의 예외 close() 방법의 버퍼링 Stream?

(주시기 바랍,어서...)

편집:그것은 나에게,또는 업데이트하는 경우 이 페이지를 보았는 두 질문과 답변 감소에 의해 하나는 지점에서 몇 분?은 사람을 즐기고 자신이 너무 많이 하는 동안 remaning 익명으?

EDIT2: 맥도웰 제공하는 매우 흥미있는 링크가 있다고 생각했을 언급하기:http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html

EDIT3:다음과 같은 맥도웰의 링크가 하락에 대한 제안 Java7 의 유사한 패턴을를 사용하여 C#패턴: http://tech.puredanger.com/java7/#resourceblock .나의 문제를 명시적으로 설명되어 있습니다.분명히도,Java7 do, 문제는 남아있다.

도움이 되었습니까?

해결책

시도/마침내 패턴은 대부분의 경우 Java 6 이하의 경우 스트림을 처리하는 올바른 방법입니다.

일부는 조용히 폐쇄 스트림을 옹호하고 있습니다. 다음과 같은 이유로 조심하십시오. Java : 스트림 취급을 엉망으로 만드는 방법


Java 7이 소개됩니다 재료를 시도하십시오:

/** transcodes text file from one encoding to another */
public static void transcode(File source, Charset srcEncoding,
                             File target, Charset tgtEncoding)
                                                             throws IOException {
    try (InputStream in = new FileInputStream(source);
         Reader reader = new InputStreamReader(in, srcEncoding);
         OutputStream out = new FileOutputStream(target);
         Writer writer = new OutputStreamWriter(out, tgtEncoding)) {
        char[] buffer = new char[1024];
        int r;
        while ((r = reader.read(buffer)) != -1) {
            writer.write(buffer, 0, r);
        }
    }
}

AutoCloseable 유형은 자동으로 닫힙니다.

public class Foo {
  public static void main(String[] args) {
    class CloseTest implements AutoCloseable {
      public void close() {
        System.out.println("Close");
      }
    }
    try (CloseTest closeable = new CloseTest()) {}
  }
}

다른 팁

문제가 있지만 웹에서 누워있는 코드는 실제로 열악합니다.

버퍼 스트림을 닫으면 아래 스트림이 닫힙니다. 당신은 정말로 그렇게하고 싶지 않습니다. 출력 스트림을 플러시하면됩니다. 또한 기본 스트림을 파일에 대한 지정하는 데 아무런 의미가 없습니다. 한 번에 하나의 바이트를 복사하기 때문에 성능이 빨라집니다 (실제로 java.io를 사용하는 경우 Transferto/TransferFrom을 사용할 수 있습니다. 우리가 그것에 관한 동안, 변수 이름이 빨라집니다. 그래서:

public static void copy(
    InputStream in, OutputStream out
) throw IOException {
    byte[] buff = new byte[8192];
    for (;;) {
        int len = in.read(buff);
        if (len == -1) {
            break;
        }
        out.write(buff, 0, len);
    }
}

당신이 자신이 시도하는 것을 많이 사용한다면, 당신은 "execute atround"관용구로 그것을 고려할 수 있습니다.

제 생각에는 Java는 범위가 끝날 때 자원을 폐쇄해야합니다. 추가하는 것이 좋습니다 private 공개 포스트 픽스 연산자로서 둘러싸는 블록의 끝에서 닫습니다.

그래,얼마나 자바 작동합니다.제어가 반전 사용자의 개체하는 방법을 알고 깨끗한 대신 개체 자체의 청소 후에 자체입니다.이것은 불행하게도 이르게 많은 정리 코드에 걸쳐 흩어져 자바 코드입니다.

C#는"사용"키워드를 자동으로 전화를 처분할 때는 객체가 범위를 벗어납니다.Java 가 없습니다.

불행히도,이 유형의 코드는 Java에서 약간 부풀어 오르는 경향이 있습니다.

그건 그렇고, Osbuffer.Read 또는 Odbuffer.Write에 대한 호출 중 하나가 예외를 던지면 해당 예외가 호출 계층 구조에 스며 들게하는 것을 원할 것입니다.

최종적으로 클라스 내부에서 닫기 ()에 대한 대단한 전화를 걸면 원래 예외가 Close ()-호출에 의해 생성 된 예외로 대체됩니다. 다시 말해, 실패한 close ()-메소드는 read () 또는 write ()에 의해 생성 된 원래 예외를 숨길 수 있습니다. 그래서, 나는 당신이 close ()에 의해 던져진 예외를 무시하고 싶다고 생각합니다. 그리고 만약 다른 방법은 던지지 않았습니다.

나는 보통 내부 시도 안에 명시적인 근접 통화를 포함하여 이것을 해결합니다.

  try {
    while (...) {
      read...
      write...
    }
    oSBuffer.close(); // exception NOT ignored here
    oDBuffer.close(); // exception NOT ignored here
  } finally {
    silentClose(oSBuffer); // exception ignored here
    silentClose(oDBuffer); // exception ignored here
  }
  static void silentClose(Closeable c)  {
    try {
      c.close();
    } catch (IOException ie) {
      // Ignored; caller must have this intention
    }
  }

마지막으로, 성능을 위해 코드는 아마도 버퍼 (읽기/쓰기 당 여러 바이트)와 함께 작동해야합니다. 숫자로 그것을 뒷받침 할 수는 없지만, 버퍼링 스트림을 맨 위에 추가하는 것보다 더 적은 통화가 더 효율적이어야합니다.

파일 복사와 같은 일반적인 IO 작업의 경우 위에 표시된 코드와 같은 코드가 휠을 재발 명합니다. 불행히도 JDK는 더 높은 수준의 유틸리티를 제공하지 않지만 Apache Commons-Io는 그렇습니다.

예를 들어, 파일 파일 및 디렉토리 작업을위한 다양한 유틸리티 방법 (복사 포함)이 포함되어 있습니다. 반면에 JDK에서 IO 지원을 실제로 사용해야한다면 ioutils 예외를 던지지 않고 가까운 독자, 작가, 스트림 등을위한 근접 QuestQuiet () 메소드 세트가 포함되어 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top