【问题标题】:Cut a file in multiple files (Java)在多个文件中剪切一个文件(Java)
【发布时间】:2016-07-31 22:05:25
【问题描述】:

我需要你的帮助。 我使用 Talend ESB,我想制作 java bean。

例如,我有这个平面文件:

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 行。

如果我的原始文件中有四个订单 ==> 我想要四个文件。

如果我的原始文件中有五个订单 ==> 我想要五个文件。

等等 .....................


这是我的起始代码。 我想分成多个文件。 我真的很困惑如何做到这一点。

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();
            }
        }
    }
}

【问题讨论】:

  • 分割文件的逻辑是什么?
  • 您好 Boris,逻辑基于字段 1855 和 1856(我的文件中的位置 7 到 11)。应该在1855年和1856年(两个文件)汇总在一起。
  • 那么就这样做吧。 1) 打开两个文件。 2) stream() 输入文件中的行。 3) 根据所讨论的字段,将行写入相应的文件。 4) 关闭文件。
  • 回到鲍里斯的问题,why do you need to split files at all - 这是一个巨大的红色警告灯,你问的是如何解决你遇到的问题,而不是问如何解决问题,几乎可以肯定的是,拆分文件甚至不是远程解决方案。
  • 告诉我我是否正确:您是否要为每个订单号创建一个新文件,并将具有该订单号的每一行写入其自己的文件中?

标签: java split apache-camel bufferedreader


【解决方案1】:

这个答案真的是用户Ranxfrom the Camel list,不是我自己的;但是,我认为它值得复制,因为它很优雅并且保持了骆驼的成语。

概念上,您希望拆分文件中的记录。然后,对于每条记录,您希望使用一些值来选择目标输出文件。

用户 Ranx 在 Camel 列表中提供的特定于 Camel 的解决方案使用了 Camel 功能:目标文件名可以从消息中的值(这是您的规范的一部分)中得出。

您拆分为记录,然后将字符串解组为某种格式,提取所需字段并将其设置为标题,将其编组回字符串,最后使用文件名中的标题值写入文件(附加)。

这在sn-p中表示:

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

或者,您可以避免编组和解组,并使用一个简单的处理器按原样读取字符串主体,并如上所述设置标题。这将是:

【讨论】:

    【解决方案2】:

    许多人似乎认为您不应该拆分文件。但是如果你必须这样做,一个简单的解决方案是读入你的文件,我在下面称之为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();
        }
    }
    

    【讨论】:

    • 感谢蒂姆的回答!它更复杂,我阻止。我的输入文件,代码 1855 或 1856 并不总是相同,它是一个订单号,我不知道我的文件中有多少不同的代码。我可以有 5、6、7 个代码和文件。对不起,我说错了:(
    • @Louisa 那么您准备好为每个订单号提供任意数量的输出文件了吗?现在我开始同意您的方法可能不正确。
    • 我需要一个按顺序排列的文件,但我可以在原始文件中有一个随机数顺序。我也觉得我走错了方向……
    • 更新您的问题并描述您要解决的实际问题。您刚刚告诉我您需要一个文件,但在 OP 中您说您需要两个文件。
    • 对不起蒂姆,我表达得很糟糕。我编辑了我的帖子,希望它更清楚......你对我的问题感兴趣真的很高兴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 2017-09-14
    • 2012-09-24
    • 2011-03-18
    相关资源
    最近更新 更多