Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with parsing CSV file with spaces and colon #80

Closed
Phalaen opened this issue Mar 12, 2021 · 5 comments
Closed

Problem with parsing CSV file with spaces and colon #80

Phalaen opened this issue Mar 12, 2021 · 5 comments
Labels
under discussion While discussing, we haven't decided on a policy yet.

Comments

@Phalaen
Copy link

Phalaen commented Mar 12, 2021

Good morning,

I'm trying to use kotlin-csv on a comma delimited file (input stream) but I think there is a problem with managing the spaces and colon.

In particular, these are the first lines of the file:

Device serial,Date ,Temperature 51 (Medium) °C
11869,2021-02-09 00:14:59,7.2
11869,2021-02-09 00:30:01,7.1
11869,2021-02-09 00:44:59,7.2
11869,2021-02-09 00:59:59,7.4
11869,2021-02-09 01:14:58,7.5
11869,2021-02-09 01:29:58,7.5
11869,2021-02-09 01:44:58,7.3
11869,2021-02-09 01:59:58,7.2
11869,2021-02-09 02:14:58,7.2
11869,2021-02-09 02:29:58,7.2
11869,2021-02-09 02:44:58,7.2
11869,2021-02-09 02:59:57,7.3
11869,2021-02-09 03:14:57,7.2
11869,2021-02-09 03:29:57,7.3
11869,2021-02-09 03:44:57,7.2
11869,2021-02-09 03:59:57,7.4

..while this is the script:

data class DataClass(
val FirstColumn: String,
val SecondColumn: String,
val ThirdColumn: String )

fun parse(data:InputStream): List?{

 val list = mutableListOf<DataClass>()

 try {
    val rows: List<List<String>> = csvReader().readAll(data)

    for (i in rows) {

 var firstColumn : String =  i[0]
 var secondColumn : String =  i[1]
 var thirdColumn : String =  i[2]

 list.add(DataClass(FirstColumn =firstColumn, SecondColumn = secondColumn,  ThirdColumn = thirdColumn))
    }

}
catch (e: Exception) {
e.printStackTrace()
}
return list
}

Unfortunately only the first column of each row is correctly identified in the output, for example (first row):
first column: 11869
second column: 2021-02-09
third colum: 0
No other colums detected.

Where is my mistake?
Thank you

@doyaaaaaken
Copy link
Owner

Hi, @Phalaen. Thank you for your feedback.
Under the hood, both to read from String and InputStream are the same in terms of parsing logic.
So, can you give me a reproductive program like the below code? (The below code correctly works.)

fun main() {
    val data = """Device serial,Date ,Temperature 51 (Medium) °C
        |11869, 2021-02-09 00:14:59, 7.2""".trimMargin()
    val rows = csvReader().readAll(data)
    println(rows) // Result: correctly parsed
}

@doyaaaaaken doyaaaaaken added the under discussion While discussing, we haven't decided on a policy yet. label Mar 15, 2021
@Phalaen
Copy link
Author

Phalaen commented Mar 15, 2021

Dear @doyaaaaaken,
thank you, this is my code:

import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.*
import androidx.lifecycle.lifecycleScope
import java.net.MalformedURLException
import java.net.URL
import com.github.doyaaaaaken.kotlincsv.dsl.csvReader

class MainActivity : AppCompatActivity() {

@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

button.setOnClickListener {
// url to download json data
val url:URL? = try {
URL(" hidden ")
}catch (e:MalformedURLException){
Log.d("Exception", e.toString())
null
}

lifecycleScope.launch(Dispatchers.IO){
url?.getStream()?.apply {

    // default dispatcher for json parsing, cpu intensive work
    withContext(Dispatchers.Default){

       // val list = parseDOMNesaTempIst(this@apply)
        val list = parse(this@apply)
        // main dispatcher for interaction with ui objects
        withContext(Dispatchers.Main){

            textView.append("\n\nReading data from website....\n")
            textView.append(list.toString())
              }
             }
            }
        }
    }
}

}

// extension function to get string data from url
fun URL.getStream(): InputStream? {
val stream = openStream()
return stream
}

data class DataClass(
val FirstColumn: String,
val SecondColumn: String,
val ThirdColumn: String )

fun parse(data:InputStream): List?{

val list = mutableListOf<DataClass>()

try {
   val rows: List<List<String>> = csvReader().readAll(data)

   for (i in rows) {

var firstColumn : String =  i[0]
var secondColumn : String =  i[1]
var thirdColumn : String =  i[2]

list.add(DataClass(FirstColumn =firstColumn, SecondColumn = secondColumn,  ThirdColumn = thirdColumn))
   }

}
catch (e: Exception) {
e.printStackTrace()
}
return list
}

In R.layout.activity_main there is only a button ("button") and a textview ("textView").
Thank you

@doyaaaaaken
Copy link
Owner

@Phalaen
I cannot reproduce that in my environment.
Can you check what the InputStream content actually is?
In your code, you can debug it just before val rows: List<List<String>> = csvReader().readAll(data) line.

Hint: You can convert InputStream into String by using the below code.

val inputStream: InputStream = TODO()
val csvContent: String = inputStream.bufferedReader().use(BufferedReader::readText)

@Phalaen
Copy link
Author

Phalaen commented Mar 15, 2021

Dear @doyaaaaaken ,
I tried converting inputstream into string and I think the problem is aready here, as the string is only partial:

Device serial,Date ,Rainfall 10 (Accumulated) mm
11869,2021-02-20,0
11869,2021-02-21,0
11869,2021-02-22,0
11869,2021-02-23,0
11869,2021-02-24,0.2
11869,2021-02-25,0
11869,2021-02-26,0
11869,2021-02-27,0

Is it normal? This never happened before to me

@Phalaen
Copy link
Author

Phalaen commented Mar 15, 2021

Solved!
Using the string text (val csvContent: String = inputStream.bufferedReader().use(BufferedReader::readText) ) parsing is correctly performed.
Thank you @doyaaaaaken !

@Phalaen Phalaen closed this as completed Mar 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
under discussion While discussing, we haven't decided on a policy yet.
Projects
None yet
Development

No branches or pull requests

2 participants