【问题标题】:Get only the first two positions of CSV in Java仅获取Java中CSV的前两个位置
【发布时间】:2019-01-04 10:07:15
【问题描述】:

我有一个包含德国汽车牌照的 csv 文件。结构如下: B,柏林,德国 第一个B是城市的第一个大写字母,第二个位置是城市,第三个位置是州

我只想要前两个位置,只有B和柏林

我知道如何在 Java 中读取 CSV 文件,但我不知道如何告诉编译器“忽略”第三个位置?

public void read(){
    InputStream inputStream = getResources().openRawResource(R.raw.carplates);

    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    try {
        String csvLine;
        while ((csvLine = reader.readLine()) != null) {
            String[] row = csvLine.split(",");
            for(int i=0; i<row.length;i++){
                Log.d("ROWS", row[i]);
            }
 }

输出是一个包含 B、柏林和德国的数组。由于有 400 个板块,因此无法手动删除 csv 文件中的状态。 这里的诀窍是什么?

提前谢谢你

[清除]

所有元素都在同一行:B,Berlin,Germany,M,Munich,Germany...

【问题讨论】:

  • 拆分后可以自己做,只是不要看第3个索引
  • for(int i=0; i
  • 不只是B,柏林,德国。有400个盘子。所以如果我只有B,柏林,德国,那么我会忽略第3个索引,但是第6个,第9个,第12个......索引呢?
  • 当你拆分行时,只需读取你想要的索引。在这种情况下为 0 和 1,始终验证数组长度是否正确以防止异常
  • @AitorFDK 适用于您的 csv 文件仅包含“B, Berlin, Germany”,但不适用于 csv 文件中有 400 个元素时。

标签: java csv


【解决方案1】:

跳过打印最后一行:

for(int i=0; i<row.length - 1; i++){
    Log.d("ROWS", row[i]);
}

如果您确定每行恰好包含 3 个值,请执行此操作。理想情况下,这些东西应该是可配置的。一般来说,您不想只记录这些内容,因此请考虑将数据映射到某个 License.class 并使用 license.getLetter()、license.getCity() 或其他任何东西

【讨论】:

【解决方案2】:

您可以更新您的 for 循环条件,使其仅读取您拥有的列表的前两个元素。

类似

public void read(){
    InputStream inputStream = getResources().openRawResource(R.raw.kfzkennzeichen);

    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    try {
        String csvLine;
        while ((csvLine = reader.readLine()) != null) {
            String[] row = csvLine.split(",");
            if (row.lenght >= 2){
               for(int i=0; i<2;i++){
                  Log.d("ROWS", row[i]);
              }
            }else{
                Log.d("Invalid Row");
            }
 }

希望这会有所帮助。

【讨论】:

    【解决方案3】:
    //ideally, this should be on config file
    int maxIndexToRead = 2;
    
    for(int i=0; i< maxIndexToRead;i++)
    {
         Log.d("ROWS", row[i]);
    }
    

    是的,Allman 风格规则; )

    【讨论】:

      【解决方案4】:

      Apache Commons CSV

      关于您的具体问题,其他答案是正确的。此外,这里是使用Apache Commons CSV 库的示例代码,可以使这项工作更容易一些。

      请注意我们如何检索 3 个字段中的每一个,但只使用前 2 个,忽略第三个(根据您的问题)。

      package com.basilbourque.example;
      
      import org.apache.commons.csv.CSVFormat;
      import org.apache.commons.csv.CSVRecord;
      
      import java.io.BufferedReader;
      import java.io.IOException;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.nio.file.Paths;
      
      public class CityLetter {
          public static void main ( String[] args ) {
              CityLetter app = new CityLetter();
              app.doit();
          }
      
          private void doit ( ) {
              try {
                  // Locate file to import and parse.
                  Path path = Paths.get( "/Users/basilbourque/CityLetter.csv" );
                  if ( Files.notExists( path ) ) { System.out.println( "ERROR - no file found for path: " + path + ". Message # f31b73b0-7ba7-4ea8-81b4-c8d768dde99d." ); }
      
                  // Read CSV file.
                  // For each row, use 2 of the 3 fields (letter, city), while ignoring the third (country).
                  BufferedReader reader = Files.newBufferedReader( path );
                  Iterable < CSVRecord > records = CSVFormat.RFC4180.parse( reader );
                  for ( CSVRecord record : records ) {
                      // B,Berlin,Germany
                      // P,Paris,France
                      // T,Tunis,Tunisia
                      String letter = record.get( 1 - 1 ); // Annoying zero-based index counting.
                      String city = record.get( 2 - 1 );
                      String country = record.get( 3 - 1 ); // Ignore.
                      // Use the 2 of 3 values.
                      System.out.println( "letter: " + letter + " | City: " + city );
      //                City city = new City( letter , city );
      //                listOfCities.add( city );
                  }
      
              } catch ( IOException e ) {
                  e.printStackTrace();
              }
          }
      }
      

      运行时。

      字母:B |城市:柏林

      字母:P |城市:巴黎

      字母:T |城市:突尼斯

      按名称引用列

      或者,您可以按名称而不是索引号来引用每一列。添加标题行,然后在 CSVFormat.RFC4180 上添加另一个调用以查找这些标题。

      请参阅my Answer 上的示例代码到类似的问题。

      【讨论】:

      • 非常感谢您提供更多信息
      【解决方案5】:

      如果你愿意,你可以消除你的 for 循环:

      public void read() {
          InputStream inputStream = getResources().openRawResource(R.raw.carplates);
      
          BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
          try {
              String csvLine;
              while((csvLine = reader.readLine()) != null) {
                  String[] row = csvLine.split(",");
                  Log.d("First capital letter of the city: ", row[0]);
                  Log.d("City: ", row[1]);
              }
          } catch(...) {
              //...
          }
      }
      

      但正如@Akceptor 在另一个答案中提到的那样,只有在您确定 CSV 始终采用这种格式时才这样做。

      如果您愿意,也可以通过这种方法轻松地将您的行转换为类实例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-18
        • 2018-09-15
        • 2011-07-15
        • 1970-01-01
        相关资源
        最近更新 更多