2

I am trying to read a fixed width file and writting it as text file ,below is the code . Input file layout length of the fields(4,10,3,5,3,1,1,5,7)

094482018-07-10 022 14012 000 0 30000A 002290{

059412018-07-10 022 14013 000 0 30000A 002290{

015172018-07-10 046 17502 000 0 30000A 001699I

scala> val inputdata = scala.io.Source.fromFile("/C:/Users/rrrrrr/Desktop/datas
tage/inputdata.txt")
inputdata: scala.io.BufferedSource = non-empty iterator

scala> val lines = inputdata.getLines
lines: Iterator[String] = non-empty iterator

scala> val matched=lines.map(l=>(l.substring(0,5).trim(),l.substring(5,5).trim()
))
matched: Iterator[(String, String)] = non-empty iterator

scala> val outputdata= new File("/C:/Users/rkumar0/Desktop/folder/output_N4.txt"
)
outputdata: java.io.File = C:\Users\rrrrrrr\Desktop\folder\output_N4.txt

scala> val writer= new BufferedWriter(new FileWriter(outputdata))
writer: java.io.BufferedWriter = java.io.BufferedWriter@759c0c14

scala> matched.foreach{line =>
     | writer.write(line)
     | writer.newLine()
     | }
<console>:19: error: overloaded method value write with alternatives:
  (x$1: Int)Unit <and>
  (x$1: String)Unit <and>
  (x$1: Array[Char])Unit
 cannot be applied to ((String, String))
       writer.write(line)
              ^

scala>

and my output file created empty.

Rupesh Kumar
  • 29
  • 1
  • 9
  • `l.substring(5,5)` is guaranteed to be an empty `String`. There's no point in adding `.trim()` to it. – jwvh Jul 11 '18 at 19:56

2 Answers2

3

The error message is telling you that write takes either an Int or a String or an Array[Char], but you are passing it a 2-Tuple of (String, String). You need to pass it either an Int, a String, or an Array[Char], not a 2-Tuple of (String, String).

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • The error message is telling you *exactly* which types are allowed. My answer is telling you *exactly* which types are allowed. What, *precisely* is it you don't understand about the error message? It would help if you could explain what you don't understand about the error message, so that the error message can be improved and other programmers don't run into the same troubles you did. – Jörg W Mittag Jul 11 '18 at 10:24
  • I am new to scala, i was trying to read a fixed width file and then perform some operation and then write to a new file, for doing the same i have written this code but it , I think i am missing something . If you have solution then kindly guide me. – Rupesh Kumar Jul 11 '18 at 10:49
1

Your lines have type of (String, String), but to write them, you should convert them to String using toString() method, and don't forget to call flush() and close() after writing:

matched.foreach(line => {
  writer.write(line.toString)
  writer.newLine()
})
writer.flush()
writer.close()

Updated solution (based on input data)

import java.io.{BufferedWriter, File, FileWriter}
import java.time.LocalDate

import scala.util.{Failure, Success, Try}

val inputData = scala.io.Source.fromFile("/C:/Users/rrrrrr/Desktop/datastage/inputdata.txt")
val lines = inputData.getLines

val boundDate = LocalDate.parse("2018-01-01")

val matched = lines.filter(line =>
  Try(LocalDate.parse(line.substring(5, 15))) match {
    case Success(date) => date.isAfter(boundDate)
    case Failure(_) => false
  })

val outputData = new File("/C:/Users/rkumar0/Desktop/folder/output_N4.txt")

val writer= new BufferedWriter(new FileWriter(outputData))

matched.foreach(line => {
  writer.write(line)
  writer.newLine()
})
writer.flush()
writer.close()

For the sample input based on you input data (with some wrong data):

094482017-06- 022 14012 000 0 30000A 002290{

094482017-326asd- 022 14012 000 0 30000A 002290{

094482017-06-10 022 14012 000 0 30000A 002290{

094482017-12-01 022 14012 000 0 30000A 002290{

094482018-07-10 022 14012 000 0 30000A 002290{

059412018-07-10 022 14013 000 0 30000A 002290{

015172018-07-10 046 17502 000 0 30000A 001699I

015172018-10-25 046 17502 000 0 30000A 001699I

The output will be:

094482018-07-10 022 14012 000 0 30000A 002290{

059412018-07-10 022 14013 000 0 30000A 002290{

015172018-07-10 046 17502 000 0 30000A 001699I

015172018-10-25 046 17502 000 0 30000A 001699I

Updated solution 2 (for comparing first 5 bytes):

val matched = lines.filter(line =>
  Try(line.substring(0, 5).toInt) match {
    case Success(n) => n > 90000
    case Failure(_) => false
  }
)
Duelist
  • 1,562
  • 1
  • 9
  • 24
  • after converting to String it is giving me bracket and , and also the length is not correct. – Rupesh Kumar Jul 11 '18 at 14:39
  • Could you share your piece of expected input and expected output? – Duelist Jul 11 '18 at 14:41
  • 094482018-07-10 022 14012 000 0 30000A 002290{ 059412018-07-10 022 14013 000 0 30000A 002290{ 015172018-07-10 046 17502 000 0 30000A 001699I above is the input, first field is of (4,10,3,5,3,1,1,5,7) i want output also to be fixed width,? My main concern is if i want to do any operation on any of the field then how will i do? – Rupesh Kumar Jul 11 '18 at 16:09
  • It would be better if you put your input and output in your question (just click _edit_). It doesn't looks good in comment. – Duelist Jul 11 '18 at 16:18
  • Hey Duelist, I have added input in question box, here you guide me how u are going to process this records just consider i want all the records greater than 2018-01-01. – Rupesh Kumar Jul 11 '18 at 17:27
  • Added the solution based on your input data – Duelist Jul 11 '18 at 18:43
  • Hey duelist Thanks!, in case if we have to get records where first 5 bytes are greater than 90000 then in that how u r going to prase it? Kindly guide TIA – Rupesh Kumar Jul 11 '18 at 19:45
  • Added the solution for this case – Duelist Jul 11 '18 at 19:56
  • It Makes sense to me Now, Thanks Bro!! – Rupesh Kumar Jul 11 '18 at 19:59