簡體   English   中英

Java從文件中讀取字符串

[英]Java reading Strings from a file

我在使用此方法時遇到麻煩。 該方法應該讀取一系列數據的文本文件(攻擊ID [int],日期[以MM / DD / YYYY格式保存的字符串],怪物[String]的名稱,位置[String]和報告者)攻擊[String]),以逗號分隔,然后將這些值放入名為MonsterAttacks的ArrayList中。 每次我運行此方法時,都會收到一個InputMismatchException。 我感覺它與日期有關,但是在這種情況下我不確定在哪里或如何使用String split()方法。 我該如何使其正常工作?

免責聲明:這是家庭作業的一部分。

提前致謝。

編輯:來自文本文件的樣本數據:

1994年12月23日,德古拉,加利福尼亞,Trisha Takinawa

1992年11月25日,哥斯拉,紐約,大衛

private void readFromFile(){
    if(!(monsterAttacks.isEmpty())) {
        monsterAttacks.clear();
        System.out.println("\nList cleared...");
    }
    System.out.println("Enter path: ");
    String pathName = getUserInput();
    File file = new File(pathName);
    Scanner read;
    MonsterAttack attack;

    try {
        read = new Scanner(file);
        do {
            int id = read.nextInt();
            String date = read.next();
            String name = read.next();
            String location = read.next();
            String reporter = read.next();
            attack = new MonsterAttack(id, date, name, location, reporter);
            monsterAttacks.add(attack);
        } while (read.hasNext());

        read.close();
    } catch(IOException e){
        e.printStackTrace();
    }

}

您告訴我們您的數據是

被逗號隔開

如果是這樣,那么您將不得不考慮這些令牌分隔符。 進行此操作的一種方法是只讀整行,然后用逗號分隔以訪問每個術語:

try {
    read = new Scanner(file);
    do {
        String line = read.nextLine();
        String[] parts = line.split(",\\s*");
        int id = Integer.parseInt(parts[0]);
        String date = parts[1];
        String name = parts[2];
        String location = parts[3];
        String reporter = parts[4];
        attack = new MonsterAttack(id, date, name, location, reporter);
        monsterAttacks.add(attack);
    } while (read.hasNext());

    read.close();
} catch(IOException e){
    e.printStackTrace();
}

我強烈建議為此使用文件讀取器,它具有您所需的一切,並且Java 8附帶的流集合提供了一些可以在給定輸入上執行的不錯的操作。

這是代碼:

    final File definitions = Paths.get("some/dir", "monster_definitions.txt").toFile();
    final BufferedReader reader = new BufferedReader(new FileReader(definitions));

    final String[] entries = reader.lines().collect(Collectors.joining()).split(")");

    for(String entry : entries){

        final String[] data = entry.substring(1, entry.lastIndexOf(entry)-1).split(",");

        final int id = Integer.parseInt(data[0]);
        final String date = data[1];
        final String name = data[2];
        final String location = data[3];
        final String reporter = data[4];

        monsterAttacks.add(new MonsterAttack(id, date, name, location, reporter));
    }

    reader.close();

現在,我們首先獲得所有行的流,然后將每條單獨的行收集到一個最終字符串中。 我們用“)”分隔該字符串,因為這是每個單獨條目的結束標記。 然后,我們遍歷每個條目並返回該條目的子字符串。 從索引1開始到最后的索引減1結束,這只是為了擺脫“(”和“)”。 現在,我們獲得了原始條目,其中包含緩存定義所需的所有信息。 我們使用“,”作為正則表達式來分割條目,從而獲得每個單獨數據條目的數組。

但是,我真的鼓勵您使用JSON作為某種類型的定義序列化和反序列化。 使用起來更容易,並且在操作數據時提供了更大的靈活性。


編輯:只是注意到您沒有為每個條目的任何拆分器。 除非每個條目都以換行符分隔。 在那種情況下,你可以做這樣的事情:

final List<String> entries = new ArrayList<>(reader.lines().collect(Collectors.toList()));

            for(String entry : entries){`

考慮到您的項目使用Java 8,您可以使用流(使用line() )簡單地操作文件數據,並將它們映射到所需的類(使用map() ),在這種情況下為MonsterAttack 就像這樣:

public void readFromFile(String path) throws Exception {
    final File definitions = Paths.get(path).toFile();
    final BufferedReader reader = new BufferedReader(new FileReader(definitions));

    monsterAttacks = reader.lines().map(line -> {
        String[] entry = line.split(",");
        return new MonsterAttack(Integer.parseInt(entry[0]), entry[1], entry[2], entry[3], entry[4]);
    }).collect(Collectors.toList());

    reader.close();
}

希望對您有所幫助。

已經提供了一些很好的答案,如果您正在研究開發結構化的應用程序,然后在這里考慮Spring Batch平面文件閱讀器,我只是想指出一個更“專業”的解決方案。

盡管我並不瘋,但我知道這是相當大的開銷,而且我知道這是一項家庭作業,並且可能是一個簡單的Java應用程序。 我只是認為這是將來的不錯參考。

使用平面文件讀取器/寫入器,您可以將平面文件映射到POJO(普通的舊Java對象)中,還可以使用Spring批處理連接操作,從而為批處理應用程序提供更好的結構。

以下是其工作原理的簡單片段(來自上面的鏈接):

@Configuration
public class CsvFileToDatabaseJobConfig {

    @Bean
    ItemReader<StudentDTO> csvFileItemReader() {
        FlatFileItemReader<StudentDTO> csvFileReader = new FlatFileItemReader<>();
        csvFileReader.setResource(new ClassPathResource("data/students.csv"));
        csvFileReader.setLinesToSkip(1);
 ...
    }

    private LineMapper<StudentDTO> createStudentLineMapper() {
        ...
    }

    private LineTokenizer createStudentLineTokenizer() {
        DelimitedLineTokenizer studentLineTokenizer = new DelimitedLineTokenizer();
        studentLineTokenizer.setDelimiter(";");
        studentLineTokenizer.setNames(new String[]{"name", "emailAddress", "purchasedPackage"});
        return studentLineTokenizer;
    }

    private FieldSetMapper<StudentDTO> createStudentInformationMapper() {
        BeanWrapperFieldSetMapper<StudentDTO> studentInformationMapper = new BeanWrapperFieldSetMapper<>();
        studentInformationMapper.setTargetType(StudentDTO.class);
        return studentInformationMapper;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM