简体   繁体   English

从Java文本文件中的两个单词之间分块数据

[英]Chunk data between two words from a text file in java

I have a .txt file where the data is in following format. 我有一个.txt文件,其中数据采用以下格式。

Start-enclosure
Standard
African Safari Enclosure
09am
05pm
Ram
Safari Enclosure for animals requiring large roaming area
30
Start-animl
Elephant
400

Giraffe
350

Lion
300
End-enclosure


Start-enclosure
Premium
Standard Australian Enclosure
09am
09pm
Shyam
Standard Enclosure for animals available in australia
30
5
Start-animl
Koala
8

Wormbat
25

Wallaby
20
End-enclosure

I want to store this data in a List<Enclosure> Like using switch case for the type (Standard, Premium) and storing data in this format 我想将此数据存储在List<Enclosure>就像对类型(标准,高级)使用开关盒并以这种格式存储数据一样

Enclosure Name
Opening Time
Closing Time
Enclosure Manager
Description
Entry Price

List<Animals> { animal name, animal weight }

How can I achieve it. 我该如何实现。 I was hoping some way to chunk data between Start-enclosure and End-enclosure and looping from the data. 我希望有一些方法可以在开始外壳结束外壳之间分数据,并从数据循环。 But how do I achieve it I am trying it but I need a direction to go straight path. 但是我要如何实现它,但是我需要一个方向。

I write below code for chunking a data based on start and end, and its working fine for me. 我在下面编写了用于基于开始和结束对数据进行分块的代码,它对我来说很好用。

You can modified start and end with enclosure 您可以修改机箱的开头和结尾

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class ChunkTest{

    static List<String> sList = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        sList = new Tester().test();
        sList.forEach((d) -> System.out.println(d));

    }

    private List<String> test() throws IOException {

        String str = "", str2 = "";
        FileInputStream fileInputStream = new FileInputStream(new File("path/to/text/file"));
        BufferedReader br = new BufferedReader(new InputStreamReader(fileInputStream));
        while ((str = br.readLine()) != null) {
            if (!str.equals("start")) {
                str2 = str2 + "\n" + str;
            }
            if (str.equals("end")) {
                sList.add(str2.replace("end", ""));
                str2 = "";
            }

        }

        return sList;
    }

}

Tested with below data: 经过以下数据测试:

start
1
2
3
4
end

start
5
6
7
8
end

Your input file's second enclosure has two lines for price, namely 30 and 5 . 输入文件的第二个附件包含两行价格,即305 Is that a typo? 那是错字吗? (because your proposed variable ' Entry Price ' is NOT a list)... And your algorithm will vary depending on the answer. (因为您建议的变量“ Entry Price不在列表中)...而且您的算法将根据答案而有所不同。

You can achieve the desired implementation with one loop. 您可以通过一个循环来实现所需的实现。 However, you have to stick to a few requirements about your input text file: 但是,您必须遵守有关输入文本文件的一些要求:

  • blank lines between enclosures can be ignored 机箱之间的空白行可以忽略
  • blank lines inside animals section can be ignored 动物部分内的空白行可以忽略
  • enclosure related fields appear before Start-animl section 与机箱相关的字段出现在“开始animl”部分之前
  • enclosure & animal fields appear in a deterministic order 围栏和动物场以确定的顺序出现

With the above requirements, you can achieve your goal, as shown in the code. 通过上述要求,您可以实现目标,如代码所示。 As you can see, the implementation does require fair bit of bookkeeping. 如您所见,该实现确实需要一定的簿记。 You should study the code and understand it. 您应该学习代码并理解它。 Also understand the implications of the above requirements within the code. 还应了解代码中上述要求的含义。 For example, code won't work if the order of fields changes unless you make corresponding code changes. 例如,除非您进行了相应的代码更改,否则如果字段顺序更改,代码将无法工作。

public class FileParser {

    static class Animal {
        String name;
        String weight;

        @Override
        public String toString() {
            return "(" + name + "," + weight + ")";
        }
    }

    static class Enclosure {

        String EnclosureName;
        String EnclosureType;
        String OpeningTime;
        String ClosingTime;
        String EnclosureManager;
        String Description;
        String EntryPrice;
        String PriceModifier;
        List<Animal> Animals;

        @Override
        public String toString() {
            return
                    "\tEnclosureName [" + EnclosureName + "]\n" +
                    "\tOpeningTime [" + OpeningTime + "]\n" +
                    "\tClosingTime [" + ClosingTime + "]\n" +
                    "\tEnclosureManager [" + EnclosureManager + "]\n" +
                    "\tDescription [" + Description + "]\n" +
                    "\tEntryPrice [" + EntryPrice + "]\n" +
                    "\tPriceModifier [" + PriceModifier + "]\n" +
                    "\tAnimals " + Animals
                    ;
        }
    }

    private static Map<String,ArrayList<Enclosure>> parse(File inputFile)
            throws IOException {

        Map<String,ArrayList<Enclosure>> enclosureMap = new HashMap<>();
        final int SECTION_NOOP = 0, SECTION_ENCLOSURE = 1, SECTION_ANIMAL = 2;
        int sectionType = SECTION_NOOP;

        try ( BufferedReader br = new BufferedReader(new FileReader(inputFile)) ) {
            String line;
            int enclosureLineNumber = 0, animalLineNumber = 0;
            String encType = "";
            Enclosure enclosure = null;
            while ( (line = br.readLine()) != null ) {

                String text = line.trim();

                // ignore blank lines
                if ( text.length() == 0 && (sectionType == SECTION_NOOP || sectionType == SECTION_ANIMAL) ) {
                    continue;
                }

                switch (text) {
                    case "Start-enclosure":
                        sectionType = SECTION_ENCLOSURE;
                        enclosure = new Enclosure();
                        enclosure.Animals = new ArrayList<>();
                        enclosureLineNumber++;
                        break;
                    case "Start-animl":
                        sectionType = SECTION_ANIMAL;
                        animalLineNumber++;
                        break;
                    case "End-enclosure":
                        sectionType = SECTION_NOOP;
                        enclosureLineNumber = 0;
                        animalLineNumber = 0;
                        if ( enclosure != null ) {
                            enclosureMap.get(encType).add(enclosure);
                        }
                        enclosure = null;
                        break;
                    default:
                        if ( enclosure != null && sectionType == SECTION_ANIMAL ) {
                            // line is from inside the Animals section
                            Animal theAnimal;
                            switch ( animalLineNumber )  {
                                case 1:
                                    theAnimal = new Animal();
                                    theAnimal.name = text;
                                    enclosure.Animals.add(theAnimal);
                                    animalLineNumber = 2;
                                    break;
                                case 2:
                                    theAnimal = enclosure.Animals.get( enclosure.Animals.size() -1 );
                                    theAnimal.weight = text;
                                    animalLineNumber = 1;
                                    break;
                                default:
                                    break;
                            }
                        } else if ( enclosure != null && sectionType == SECTION_ENCLOSURE ) {
                            // line is from the Enclosure (before Animals)
                            switch (enclosureLineNumber) {
                                case 1:
                                    encType = text;
                                    enclosure.EnclosureType = text;
                                    if ( !enclosureMap.containsKey(encType) ) {
                                        enclosureMap.put( encType, new ArrayList<>() );
                                    }
                                    break;
                                case 2:
                                    enclosure.EnclosureName = text;
                                    break;
                                case 3:
                                    enclosure.OpeningTime = text;
                                    break;
                                case 4:
                                    enclosure.ClosingTime = text;
                                    break;
                                case 5:
                                    enclosure.EnclosureManager = text;
                                    break;
                                case 6:
                                    enclosure.Description = text;
                                    break;
                                case 7:
                                    enclosure.EntryPrice = text;
                                    break;
                                case 8:
                                    enclosure.PriceModifier = text;
                                    break;
                                default:
                                    break;
                            }
                            enclosureLineNumber++;
                        } else {
                            // ignore lines that are not part of Enclosure
                        }
                        break;
                }

            }
        }

        return enclosureMap;
    }

    public static void main(String[] args) throws IOException {
        if ( args.length != 1 ) {
            System.err.println("Missing filename argument");
            System.exit(1);
        }
        File inputFile = new File(args[0]);
        if ( !inputFile.canRead() ) {
            System.err.println(args[0] + ": does not exist or unreadable");
        }

        Map<String,ArrayList<Enclosure>> enclosureMap = parse(inputFile);

        enclosureMap.entrySet().forEach((entry) -> {
            System.out.println("Enclosures of Type = " + entry.getKey() + "\n");
            entry.getValue().forEach((enclosure) -> {
                System.out.println(enclosure + "\n");
            });
        });
    }

}

For your input file, the output produced by above code would be: 对于您的输入文件,以上代码产生的输出为:

Enclosures of Type = Standard

    EnclosureName [African Safari Enclosure]
    OpeningTime [09am]
    ClosingTime [05pm]
    EnclosureManager [Ram]
    Description [Safari Enclosure for animals requiring large roaming area]
    EntryPrice [30]
    PriceModifier [null]
    Animals [(Elephant,400), (Giraffe,350), (Lion,300)]

Enclosures of Type = Premium

    EnclosureName [Standard Australian Enclosure]
    OpeningTime [09am]
    ClosingTime [09pm]
    EnclosureManager [Shyam]
    Description [Standard Enclosure for animals available in australia]
    EntryPrice [30]
    PriceModifier [5]
    Animals [(Koala,8), (Wormbat,25), (Wallaby,20)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM