11.5: Read and Write a file 1:1

Posted by Stefan Marquardt on 24-Mar-2016 06:37

Hi,

I noticed that this code is killing empty lines (I tried it with a normal df file).
Here the shortest example:

DEF STREAM s1.
DEF STREAM s2.
def var cLine as char no-undo.

INPUT STREAM s1 FROM value("c:\temp\db.df").
output stream s2 to value("c:\temp\db_new.df").

REPEAT:
  IMPORT STREAM s1 UNFORMATTED cLine.
  put stream s2 unformatted cLine skip.
end.

How I can prevent that I miss empty lines in the new file?

Posted by George Potemkin on 24-Mar-2016 07:11

"~n" instead of SKIP:

put stream s2 unformatted cLine "~n".

All Replies

Posted by Brian K. Maher on 24-Mar-2016 06:44

DEF STREAM s1.
DEF STREAM s2.
def var cLine as char no-undo.

INPUT STREAM s1 FROM value("c:\temp\db.df").
output stream s2 to value("c:\temp\db_new.df").

REPEAT:
  IMPORT STREAM s1 UNFORMATTED cLine.
  if length(cLine) > 0 then

    put stream s2 unformatted cLine skip.

  else

      put stream s2 unformatted skip(1).end.

 
 

Posted by Stefan Marquardt on 24-Mar-2016 06:52

Hi Brian,

that's ABL typically, more a workaround.

No other chance to tell ABL write and don't be too "clever"?

Stefan

Posted by Brian K. Maher on 24-Mar-2016 07:02

Stefan,
 
I don’t know of anything else to do.  The cLine variable is in essence null so you have to deal with that.  I tried doing SKIP(2) but that added extra lines.
 
Brian

Posted by Stefan Marquardt on 24-Mar-2016 07:08

Thank Brian

Posted by James Palmer on 24-Mar-2016 07:09

If the files aren't too big I've taken to COPY-LOB the file into a LONGCHAR and processing like I would any character variable. So in this case using the new line char as the text delimiter. I find it less susceptible to such strange things like you're experiencing.

Posted by George Potemkin on 24-Mar-2016 07:11

"~n" instead of SKIP:

put stream s2 unformatted cLine "~n".

Posted by Brian K. Maher on 24-Mar-2016 07:16

George is the winner!
 
I never thought about using “~n”.

Posted by Patrick Tingen on 24-Mar-2016 15:15

James' answer is not so bad either. I have taken this approach more than once myself too. Something along the lines of the below code to adjust the line you read in on the fly and write it back to disk.

DEFINE VARIABLE cDataIn  AS LONGCHAR  NO-UNDO.
DEFINE VARIABLE cDataOut AS LONGCHAR  NO-UNDO.
DEFINE VARIABLE cLine    AS CHARACTER NO-UNDO.
DEFINE VARIABLE iLine    AS INTEGER   NO-UNDO.

COPY-LOB FILE "c:\temp\data-in.txt" TO cDataIn.

DO iLine = 1 TO NUM-ENTRIES(cDataIn,'~n'):
  cLine = ENTRY(iLine,cDataIn,'~n').

  IF <some_condition> THEN 
  DO:
    <do_some_things_to_cLine>
  END.

  cDataOut = cDataOut + cLine + '~n'.
END. 

COPY-LOB cDataOut TO FILE "c:\temp\data-out.txt".

Posted by Thomas Mercer-Hursh on 24-Mar-2016 15:26

I second that Patrick's approach is one I am fond of as well.  It is surprising, for example, how quickly one can get a line count that way.  Of course, that doesn't even require the loop!

Posted by Stefan Drissen on 24-Mar-2016 16:15

Please beware with the easy coding that longchars seem to bring to the table. Large longchars need to be treated with care! Counting the number of lines in a longchar for every iteration of a loop is not something you really want to do.

Concatenating longchars gets slower and slower until it crawls - see Abe's blog - blog.abevoelker.com/.../

Posted by Stefan Drissen on 24-Mar-2016 16:16

Oh and ~n annoys Windows notepad users - you then want a ~r~n (when creating the file on a non-windows AppServer)

Posted by gus on 24-Mar-2016 16:38

> On Mar 24, 2016, at 5:16 PM, Stefan Drissen wrote:

>

> Please beware with the easy coding that longchars seem to bring to the table. Large longchars need to be treated with care! Counting the number of lines in a longchar for every iteration of a loop is not something you really want to do.

and is feature creep !!!! the number of lines was not required in the original problem statement.

Posted by Thomas Mercer-Hursh on 24-Mar-2016 16:53

Please beware with the easy coding that longchars seem to bring to the table. Large longchars need to be treated with care! Counting the number of lines in a longchar for every iteration of a loop is not something you really want to do.

Putting in in a large category of things where something doesn't change in a loop and one doesn't want to re-evaluate it on every iteration of the loop.  Not unique to longchars.  Likewise, one wouldn't want to use a loop to count lines because num-entries does this for you ... again, one of a long list of don't do things the hard way when an easy way exists.

Which said, if one restates the problem such that one needs a loop and there is no simple function to get the answer, one might very well *want* to do the thing, even if it weren't terribly fast, simply because that is the problem to be solved.

Posted by gus on 24-Mar-2016 17:12

> On Mar 24, 2016, at 5:54 PM, Thomas Mercer-Hursh wrote:

>

> Please beware with the easy coding that longchars seem to bring to the table. Large longchars need to be treated with care! Counting the number of lines in a longchar for every iteration of a loop is not something you really want to do.

should not do with char either.

or count anything else either each itration of a loop.

cultivating and using the right habits helps in these matters.

This thread is closed