如何在Java中从文本文件中读取逗号分隔的值?

11

我有一个包含地图上不同点的纬度和经度值的文本文件。

如何将我的字符串分割为纬度和经度? 除了逗号之外,使用其他分隔符(例如空格或制表符)进行这些类型的操作的一般方法是什么?

示例文件:

28.515046280572285,77.38258838653564
28.51430151808072,77.38336086273193
28.513566177802456,77.38413333892822
28.512830832397192,77.38490581512451
28.51208605426073,77.3856782913208
28.511341270865113,77.38645076751709
这是我正在使用的代码来从文件中读取数据:
try(BufferedReader in = new BufferedReader(new FileReader("C:\\test.txt"))) {
    String str;
    while ((str = in.readLine()) != null) {
        System.out.println(str);
    }
}
catch (IOException e) {
    System.out.println("File Read Error");
}

如果您喜欢使用,OpenCSV是一个流行的库。详情请见:http://opencsv.sourceforge.net/ 此外,还有一些其他关于类似主题的stackoverflow问题:- https://dev59.com/u3VD5IYBdhLWcg3wE3No - https://dev59.com/EXVC5IYBdhLWcg3wtzyt - Leon
6个回答

33
你可以使用 String.split() 方法:
String[] tokens = str.split(",");

接着使用Double.parseDouble()方法将字符串值解析为double类型。

double latitude = Double.parseDouble(tokens[0]);
double longitude = Double.parseDouble(tokens[1]);

其他包装类也存在类似的解析方法,例如IntegerBoolean等。


非常感谢,运行得非常好。 - rishiag
7
请注意,String.split 方法需要使用正则表达式作为分隔符。如果你想确保没有出现任何意外情况(例如 .|),你可以先通过 Pattern.quote() 方法处理分隔符:str.split(Pattern.quote("."))(或者手动进行转义)。 - ratchet freak
@AVD :: 你在上面展示的文本文件中得到了第一行吗?我无法获取第一行的内容...其余部分都很好。 - NeverGiveUp161
@user3560140 这段代码片段解释了Split方法的用法。如果您的代码有任何问题,请提一个新问题。 - KV Prajapati
1
@AVD:我猜解决方案是从文本文件中读取逗号分隔的值?但它并没有正确地执行。在读取时,它没有读取该文本文件中的第一个值。因此,如果有人将其用作示例,他会不必要地遇到问题。这就是通过评论提出它的原因。 - NeverGiveUp161

4

使用OpenCSV来保证可靠性。在这些情况下,不应该使用Split。以下是我自己程序的一段片段,非常简单明了。我会检查是否指定了分隔符字符,并在有指定时使用它,否则我会使用OpenCSV中的默认值(逗号)。然后我读取标题和字段。

CSVReader reader = null;
try {
    if (delimiter > 0) {
        reader = new CSVReader(new FileReader(this.csvFile), this.delimiter);
    }
    else {
        reader = new CSVReader(new FileReader(this.csvFile));
    }

    // these should be the header fields
    header = reader.readNext();
    while ((fields = reader.readNext()) != null) {
        // more code
    }
catch (IOException e) {
    System.err.println(e.getMessage());
}

2

如果要按逗号(,)分割字符串,请使用str.split(","),如果要按制表符分割,请使用str.split("\\t")

    try {
        BufferedReader in = new BufferedReader(
                               new FileReader("G:\\RoutePPAdvant2.txt"));
        String str;

        while ((str = in.readLine())!= null) {
            String[] ar=str.split(",");
            ...
        }
        in.close();
    } catch (IOException e) {
        System.out.println("File Read Error");
    }

1

使用BigDecimal,而不是double

adatapost的回答正确地使用了String::split,但错误地使用了double来表示您的经纬度值。 float/Floatdouble/Double类型使用浮点技术,为执行速度而牺牲精度

相反,使用BigDecimal来正确表示您的经纬度值。

使用Apache Commons CSV

同时,最好让像Apache Commons CSV这样的库来执行读写CSV制表符分隔文件的任务。

示例应用程序

以下是一个完整的示例应用程序,使用Commons CSV库。该应用程序先写入数据文件,然后再读取该文件。它使用String::split进行写入。并且该应用程序使用BigDecimal对象来表示您的经纬度值。

package work.basil.example;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;

import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class LatLong
{
    //----------|  Write  |-----------------------------
    public void write ( final Path path )
    {
        List < String > inputs =
                List.of(
                        "28.515046280572285,77.38258838653564" ,
                        "28.51430151808072,77.38336086273193" ,
                        "28.513566177802456,77.38413333892822" ,
                        "28.512830832397192,77.38490581512451" ,
                        "28.51208605426073,77.3856782913208" ,
                        "28.511341270865113,77.38645076751709" );

        // Use try-with-resources syntax to auto-close the `CSVPrinter`.
        try ( final CSVPrinter printer = CSVFormat.RFC4180.withHeader( "latitude" , "longitude" ).print( path , StandardCharsets.UTF_8 ) ; )
        {
            for ( String input : inputs )
            {
                String[] fields = input.split( "," );
                printer.printRecord( fields[ 0 ] , fields[ 1 ] );
            }
        } catch ( IOException e )
        {
            e.printStackTrace();
        }
    }

    //----------|  Read  |-----------------------------
    public void read ( Path path )
    {
        // TODO: Add a check for valid file existing.

        try
        {
            // Read CSV file.
            BufferedReader reader = Files.newBufferedReader( path );
            Iterable < CSVRecord > records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse( reader );
            for ( CSVRecord record : records )
            {
                BigDecimal latitude = new BigDecimal( record.get( "latitude" ) );
                BigDecimal longitude = new BigDecimal( record.get( "longitude" ) );
                System.out.println( "lat: " + latitude + " | long: " + longitude );
            }
        } catch ( IOException e )
        {
            e.printStackTrace();
        }
    }

    //----------|  Main  |-----------------------------
    public static void main ( String[] args )
    {
        LatLong app = new LatLong();

        // Write
        Path pathOutput = Paths.get( "/Users/basilbourque/lat-long.csv" );
        app.write( pathOutput );
        System.out.println( "Writing file: " + pathOutput );

        // Read
        Path pathInput = Paths.get( "/Users/basilbourque/lat-long.csv" );
        app.read( pathInput );

        System.out.println( "Done writing & reading lat-long data file. " + Instant.now() );
    }

}

十四位小数可能已经足够了... https://gis.stackexchange.com/a/8674 - Josh Lee

0

你也可以使用java.util.Scanner类。

private static void readFileWithScanner() {
    File file = new File("path/to/your/file/file.txt");

    Scanner scan = null;

    try {
        scan = new Scanner(file);

        while (scan.hasNextLine()) {
            String line = scan.nextLine();
            String[] lineArray = line.split(",");
            // do something with lineArray, such as instantiate an object
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        scan.close();
    }
}

0

//lat=3434&lon=yy38&rd=1.0&| 以该格式输出结果

public class ReadText {
    public static void main(String[] args) throws Exception {
        FileInputStream f= new FileInputStream("D:/workplace/sample/bookstore.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(f));
        String strline;
        StringBuffer sb = new StringBuffer();
        while ((strline = br.readLine()) != null)
        {
            String[] arraylist=StringUtils.split(strline, ",");
            if(arraylist.length == 2){
                sb.append("lat=").append(StringUtils.trim(arraylist[0])).append("&lon=").append(StringUtils.trim(arraylist[1])).append("&rt=1.0&|");

            } else {
                System.out.println("Error: "+strline);
            }
        }
        System.out.println("Data: "+sb.toString());
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接