【问题标题】:How can I read comma separated values from a text file in Java?如何从 Java 中的文本文件中读取逗号分隔值?
【发布时间】:2012-06-13 04:24:54
【问题描述】:

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

如何将我的字符串拆分为纬度和经度?使用其他分隔符(如空格或制表符等)执行此类操作的一般方法是什么? 示例文件:

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

【问题讨论】:

标签: java string io


【解决方案1】:

使用BigDecimal,而不是double

Answer by adatapost 使用 String::split 是正确的,但使用 double 表示您的经纬度值是错误的。 float/Floatdouble/Double 类型使用 floating-point technology 其中 trades away accuracy 来提高执行速度。

改为使用BigDecimal 来正确表示您的经纬度值。

使用 Apache Commons CSV

另外,最好让Apache Commons CSV 之类的库来执行读取和写入CSVTab-delimited 文件的繁琐工作。

示例应用

这是一个使用该 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() );
    }

}

【讨论】:

【解决方案2】:

//lat=3434&amp;lon=yy38&amp;rd=1.0&amp;| 以该格式显示 o/p

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

【讨论】:

    【解决方案3】:

    您可以使用String.split() 方法:

    String[] tokens = str.split(",");
    

    之后,使用Double.parseDouble()方法将字符串值解析为double。

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

    其他包装类中也存在类似的解析方法 - IntegerBoolean 等。

    【讨论】:

    • 非常感谢。像魅力一样工作。
    • @user1425223 请注意 String.split 采用正则表达式,如果您想确保不会发生任何有趣的事情(例如 .|),您可以首先通过 Pattern.quote() 传递分隔符:@ 987654333@(或手动转义)
    • @AVD :: 你得到了上面显示的文本文件的第一行吗?我无法得到第一行的内容...其余的都很好。跨度>
    • @user3560140 该代码 sn -p 解释了Split 方法的用法。如果您的代码有问题,请提出一个新问题。
    • @AVD:我猜提供的解决方案是从文本文件中读取逗号分隔的值?它不正确。读取它时不会读取该文本文件中的第一个值。所以如果有人以此为例,他会不必要地遇到问题。这就是通过评论提出来的原因。
    【解决方案4】:

    要使用逗号(,)分割字符串,使用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");
        }
    

    【讨论】:

      【解决方案5】:

      您也可以使用 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();
          }
      }
      

      【讨论】:

        【解决方案6】:

        使用 OpenCSV 来提高可靠性。永远不应该将拆分用于此类事情。 这是我自己的程序中的一个 sn-p,它非常简单。我检查是否指定了分隔符,如果是,则使用此分隔符,否则我使用 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());
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多