복붙노트

[SCALA] 어떻게 체인 여러 가지에는 InputStream 하나의 InputStream에

SCALA

어떻게 체인 여러 가지에는 InputStream 하나의 InputStream에

자바 (또는 스칼라)에서 하나의 연속의 InputStream에 체인을 여러에는 InputStream에 대한 ideomatic 방법이 있는지 궁금 하군요.

내가 무엇을 필요하는 것은 내가 FTP-서버에서 네트워크를 통해로드하는 것이 플랫 파일을 구문 분석하는 것입니다. 내가 뭘 원하는 파일 [1..N]을 가지고 스트림을 열고 하나 개의 스트림으로 그들을 결합하는 것입니다. 파일 1이 종료된다 때, 나는 fileN의 끝에 도달 할 때까지, 그래서 파일 2에서 읽기를 시작합니다.

나는 특정 순서로이 파일을 읽을 필요가, 데이터는 하나의 데이터가 다른 파일의 데이터에 의존하므로 barches 파일을 생성하는 기존 시스템에서 오는,하지만 내 도메인 로직 인터페이스를 단순화하기 위해 하나 개의 연속적인 스트림으로 그들을 처리하고 싶습니다 .

나는 주변 검색 및 PipedInputStream를 찾았지만, 내가 필요하다 긍정적 아니에요. 예 도움이 될 것입니다.

해결법

  1. ==============================

    1.그것은 JDK에 바로 거기입니다! 을 SequenceInputStream의의 JavaDoc을 인용 :

    그것은 JDK에 바로 거기입니다! 을 SequenceInputStream의의 JavaDoc을 인용 :

    을 SequenceInputStream 만이 허용하는 동안에는 InputStream의 임의의 수를 연결하는 원한다. 을 SequenceInputStream는 또한의 InputStream이기 때문에하지만 당신은 재귀 (둥지를) 적용 할 수 있습니다 :

    new SequenceInputStream(
        new SequenceInputStream(
            new SequenceInputStream(file1, file2),
            file3
        ),
        file4
    );
    

    ... 당신은 아이디어를 얻을.

  2. ==============================

    2.이것은 토마스 Nurkiewicz의 응답에서 볼 수 있듯이, 자바에서 간단 SequencedInputStream를 사용하여 수행됩니다. 나는 "내 라이브러리 포주"패턴을 통해 일부 스칼라-Y 선 (善)을 추가, 그래서 나는, 최근 프로젝트에서 반복적으로이 작업을 수행했다.

    이것은 토마스 Nurkiewicz의 응답에서 볼 수 있듯이, 자바에서 간단 SequencedInputStream를 사용하여 수행됩니다. 나는 "내 라이브러리 포주"패턴을 통해 일부 스칼라-Y 선 (善)을 추가, 그래서 나는, 최근 프로젝트에서 반복적으로이 작업을 수행했다.

    object StreamUtils {
      implicit def toRichInputStream(str: InputStream) = new RichInputStream(str)
    
      class RichInputStream(str: InputStream) {
    // a bunch of other handy Stream functionality, deleted
    
        def ++(str2: InputStream): InputStream = new SequenceInputStream(str, str2)
      }
    }
    

    다음과 같이두고, 나는 스트림 시퀀싱을 수행 할 수 있습니다

    val mergedStream = stream1++stream2++stream3
    

    또는

    val streamList = //some arbitrary-length list of streams, non-empty
    val mergedStream = streamList.reduceLeft(_++_)
    
  3. ==============================

    3.다른 해결책은 : 제 입력 스트림의리스트를 생성하고, 입력 스트림의 시퀀스를 생성 :

    다른 해결책은 : 제 입력 스트림의리스트를 생성하고, 입력 스트림의 시퀀스를 생성 :

    List<InputStream> iss = Files.list(Paths.get("/your/path"))
            .filter(Files::isRegularFile)
            .map(f -> {
                try {
                    return new FileInputStream(f.toString());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }).collect(Collectors.toList());
    
    new SequenceInputStream(Collections.enumeration(iss)))
    
  4. ==============================

    4.여기에 벡터를 사용하여 더 우아한 솔루션입니다,이 자바에 대한 안드로이드 특별히하지만 사용 벡터입니다

    여기에 벡터를 사용하여 더 우아한 솔루션입니다,이 자바에 대한 안드로이드 특별히하지만 사용 벡터입니다

        AssetManager am = getAssets();
        Vector v = new Vector(Constant.PAGES);
        for (int i =  0; i < Constant.PAGES; i++) {
            String fileName = "file" + i + ".txt";
             InputStream is = am.open(fileName);
             v.add(is);
        }
        Enumeration e = v.elements();
        SequenceInputStream sis = new SequenceInputStream(e);
        InputStreamReader isr = new InputStreamReader(sis);
    
        Scanner scanner = new Scanner(isr);   // or use bufferedReader
    
  5. ==============================

    5.다음을 병합하는 간단한 스칼라 버전의 반복자 [의 InputStream]

    다음을 병합하는 간단한 스칼라 버전의 반복자 [의 InputStream]

    import java.io.{InputStream, SequenceInputStream}
    import scala.collection.JavaConverters._
    
    def concatInputStreams(streams: Iterator[InputStream]): InputStream =
      new SequenceInputStream(streams.asJavaEnumeration)
    
  6. from https://stackoverflow.com/questions/14295099/how-to-chain-multiple-different-inputstreams-into-one-inputstream by cc-by-sa and MIT license