2016-07-31 3 views
2

당신의 도움이 필요합니다. 나는 Talend ESB를 사용하는데 자바 빈을 만들고 싶다.여러 파일로 파일 잘라 내기 (Java)

예를 들어, 나는이 플랫 파일이 : 내 예에서

11886 1855 0000004309000 
11886 1855 0000057370000 
11886 1856 0000057374001  
11886 1856 0000057375000  

내가 2 개 파일 (메시지), "1855"과 "1856"의 필터를 원하는을 (그것은 주문의 수이다).

첫 번째 파일 :

11886 1855 0000004309000 
11886 1855 0000057370000 

두 번째 파일 :

11886 1856 0000057374001  
11886 1856 0000057375000 

편집 : 는하지만 파일 당 주문 번호를 알고하지 않습니다.

내 원본 파일에 3 개의 주문 (각각 3 줄)이있는 경우 ==> 각 주문의 3 줄에 3 개의 파일이 필요합니다.

원본 파일에 4 개의 주문이있는 경우 ==> 네 개의 파일이 필요합니다.

원본 파일에 5 개의 주문이있는 경우 ==> 5 개의 파일을 원합니다. 에

등 .......................


이 내 시작 코드입니다. 여러 파일로 분할하고 싶습니다. 나는 이것을하는 방법에 정말로 붙어있다.

package beans; 

import java.io.BufferedReader; 
import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.util.HashMap; 
import java.util.LinkedHashMap; 
import java.util.Map; 
import org.apache.camel.*; 


public class bean_test implements Processor{ 

    private static final String ENDPOINT_NAME = "Endpoint"; 
    private static final String END_TAG_ENDPOINT_NAME = "endEndpoint"; 
    private static final int NUMERO_SITE_START_POSITION = 6; 
    private static final int NUMERO_SITE_END_POSITION = 11; 


    @Override 
    public void process(Exchange exchange) throws Exception { 

     ProducerTemplate producerTemplate = exchange.getContext().createProducerTemplate(); 
     String ropEndpoint = exchange.getIn().getHeader(ENDPOINT_NAME, String.class); 
     String endRopEndpoint = exchange.getIn().getHeader(END_TAG_ENDPOINT_NAME, String.class); 
     InputStream is = new ByteArrayInputStream(exchange.getIn().getBody(String.class).getBytes()); 
     aggregateBody(producerTemplate, is, ropEndpoint, endRopEndpoint, new HashMap<String, Object>(exchange.getIn().getHeaders())); 

    } 

    private void aggregateBody(ProducerTemplate producerTemplate, InputStream content, String ropEndPoint, String endRopEndpoint, Map<String, Object> headers){ 
     BufferedReader br = new BufferedReader(new InputStreamReader(content)); 
     String line; 
     Map<String, StringBuilder> articles = new LinkedHashMap<String, StringBuilder>(); 
     StringBuilder aggregateFile = new StringBuilder(); 
     try { 
      String lineId = null; 
      while((line = br.readLine()) != null){ 
      lineId = line.substring(NUMERO_SITE_START_POSITION, NUMERO_SITE_END_POSITION); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     finally{ 
      try { 
       if(br != null)br.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

감사합니다.

루이지애나.

편집 : 내 새 코드가 있지만 파일을 반환하는 방법을 모르겠습니다.

package beans; 

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.ByteArrayInputStream; 
import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.Set; 
import java.util.TreeSet; 

import org.apache.camel.*; 


public class bean_test implements Processor{ 

    private static final String ENDPOINT = "aggregateEndpoint"; 
    private static final int NUMERO_SITE_START_POSITION = 46; 
    private static final int NUMERO_SITE_END_POSITION = 55; 


    @Override 
    public void process(Exchange exchange) throws Exception { 

     ProducerTemplate producerTemplate = exchange.getContext().createProducerTemplate(); 
     String endpoint = exchange.getIn().getHeader(ENDPOINT, String.class); 
     InputStream is = new ByteArrayInputStream(exchange.getIn().getBody(String.class).getBytes()); 
     aggregateBody(producerTemplate, is, endpoint, new HashMap<String, Object>(exchange.getIn().getHeaders())); 

    } 

    private void aggregateBody(ProducerTemplate producerTemplate, InputStream content, String endpoint, Map<String, Object> headers){ 
     BufferedReader br = new BufferedReader(new InputStreamReader(content)); 
     String line; 
     Set<String> order=new TreeSet<String>(); 

     try { 
      String lineId = null; 
      while((line = br.readLine()) != null){ 
       lineId = line.substring(NUMERO_SITE_START_POSITION, NUMERO_SITE_END_POSITION); 
       order.add(lineId); 
      } 

      for(int i=0;i<order.size();i++){ 
       String key = "file" + i; 
       File F = new File(key); 
       Iterator it = order.iterator(); 
       FileWriter fw = new FileWriter(F.getAbsoluteFile()); 
       BufferedWriter bw = new BufferedWriter(fw); 

       while((line = br.readLine()) != null){ 
        while(it.hasNext()){ 
         lineId = line.substring(NUMERO_SITE_START_POSITION, NUMERO_SITE_END_POSITION); 
         if (lineId.equals(it.next())) { 
          bw.write(line); 
         } 
        } 

       } 
      } 


     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     finally{ 
      try { 
       if(br != null)br.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
+0

파일을 분할하는 논리는 무엇입니까? –

+0

안녕하세요 보리스, 로직은 필드 1855 및 1856 (내 파일에서 위치 7-11)을 기반으로합니다. 1855 및 1856 (두 개의 파일)에 함께 집계해야합니다. – Louisa

+0

글쎄요. 1) 두 개의 파일을 엽니 다. 2)'stream()'입력 파일의 행. 3) 해당 필드에 따라 해당 파일에 행을 작성하십시오. 4) 파일을 닫으십시오. –

답변

1

이 답변은 사용자 Ranx, from the Camel list에 의해 정말, 아니 내 자신; 그러나 우아하고 카멜 관용구를 유지하기 때문에 재현 할 가치가 있다고 생각합니다.

개념적으로는이고, 으로 나누어 파일에 기록하고 싶습니다. 그런 다음 각 레코드에 대해 값을 사용하려면 대상 출력 파일을 선택하십시오. enter image description here

낙타 목록에 Ranx 사용자 에서 제공하는 낙타 특정 솔루션은 카멜 기능을 사용 : 대상 파일 이름 (당신 사양의 일부) 메시지의 값에서 파생 될 수있다.

enter image description here 당신은 어떤 형식으로 문자열을 비 정렬 화, 필요한 필드를 끌어와 헤더로 설정, 문자열로 다시 마샬링, 그리고 마지막으로 헤더를 사용하여, (추가) 파일에 기록, 기록으로 분할 파일 이름의 값.

은 코드에서 표현되었다 :

from("file:/inbox") 
.split(body()) 
.unmarshal(dataFormat) 
.setHeader("fileName",simple("${body.identifier}")) 
.marshal(dataFormat) 
.to("file:/outbox/?fileName=${header.fileName}.txt&fileExist=Append") 

또는, 당신은 아마 정렬 화 및 비 정렬 화를 방지하고,있는 그대로 문자열 본문을 읽을 수있는 간단한 프로세서를 사용하고, 위와 같이 헤더를 설정할 수 있습니다. 이것은 : enter image description here

+0

Waahhho 그것이 작동합니다! yuou 매우 mucch 주셔서 감사합니다 : D 조! – Louisa

0

많은 사람들이 파일을 나누어서는 안됩니다. 그러나이 작업을 수행해야한다면 간단한 해결책은 아래 파일 flatfile.txt으로 파일을 읽고 각 줄의 두 번째 항목이 1855 또는 1856인지 확인하는 것입니다. 각각의 경우 출력을 해당 파일에 씁니다.

try { 
    File f1 = new File("f1855.txt"); 
    File f2 = new File("f1856.txt"); 

    if (!f1.exists()) { 
     f1.createNewFile(); 
    } 
    FileWriter fw1 = new FileWriter(f1.getAbsoluteFile()); 
    BufferedWriter bw1 = new BufferedWriter(fw1); 

    if (!f2.exists()) { 
     f2.createNewFile(); 
    } 
    FileWriter fw2 = new FileWriter(f2.getAbsoluteFile()); 
    BufferedWriter bw2 = new BufferedWriter(fw2); 

    String currLine; 
    BufferedReader br = new BufferedReader(new FileReader("flatfile.txt")); 

    while ((currLine = br.readLine()) != null) { 
     String[] parts = currLine.split(" "); 
     if (parts[1].equals("1855")) { 
      bw1.write(currLine); 
     } 
     else if (parts[1].equals("1856")) { 
      bw2.write(currLine); 
     } 
     else { 
      System.out.println("Found a line which did not match 1855 or 1856."); 
     } 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} finally { 
    try { 
     if (br != null) br.close(); 
     if (bw1 != null) bw1.close(); 
     if (bw2 != null) bw2.close(); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } 
} 
+0

감사합니다. Tim이 대답을합니다. 내 입력 파일, 코드 1855 또는 1856이 항상 같은 것은 아니며, 주문 번호이며 몇 개의 다른 코드인지 잘 모릅니다. 내 파일에 5, 6, 7 코드와 파일을 가질 수 있습니다. 죄송합니다. misspoke :( – Louisa

+0

@Louisa 그렇다면 각 주문 번호에 대해 임의의 수의 출력 파일을 준비 할 준비가 되었습니까? –

+0

주문으로 하나의 파일이 필요하지만 원본 파일에 임의의 번호 순서를 사용할 수 있습니다. 나는 또한 내가 생각하기에, 잘못된 방향으로 가고 ... – Louisa