Search notes:

SAS: File data buffer

fopen opens an external file and allocates a special buffer: the file data buffer (FDB)
fread then reads a record from the external file and copies it into the FDB.
fsep specifies the token delimiters for fget.
fcol returns the current column position in the FDB.
fget assigns values from the FDB to data step variables.
fput movesdat to the FDB. It starts at the position indicated by fcol.
write writes the content of the FDB to the external file.
Finally, fclose closes the external file.
The file pointer is explicitly positioned with fpoint, fnote, frewind.

Writing a file

%let dirname=/tmp;
%let filename=&dirname/tq84.txt;
filename filref "&filename";

%macro checkRC(func);
  rc = &func;
  if rc ~= 0 then do;
     err  =sysmsg();
     %let funcQ=%sysfunc(quote(&func));
     put  "Error with " &funcQ;
     put  err;
     abort;
  end;
%mend  checkRC;

%macro writeLine(text);
  %checkRC(%str(fput  (fil, "&text")))
  %checkRC(%str(fwrite(fil, ' ')))
%mend  writeLine;

data _null_;
  fil = fopen('filref', 'o', , 'v');
  if fil = 0 then do;
     err = sysmsg();
     put "Could not open file";
     put  err;
  end;

  %writeLine(This is the first line.)
  %writeLine(This is the second line.)
  %writeLine(Here comes the third line.)
  %writeLine(And the fourth one.)
  %writeLine(%quote(Finally, this is the last (that is: fifth) line.))

 %checkRC(%nrstr(fclose(fil)))
run;
Github repository about-SAS, path: /programming/files/file-data-buffer/write-file.sas

Reading the written file

%let dirname=/tmp;
%let filename=&dirname/tq84.txt;
filename filref "&filename";

%macro checkRC(func);
  rc = &func;
  if rc ~= 0 then do;
     err  =sysmsg();
     %let funcQ=%sysfunc(quote(&func));
     put  "Error with " &funcQ;
     put  err;
     abort;
  end;
%mend  checkRC;

%macro readLine;
  %checkRC(%str(fread(fil)))
  %checkRC(%str(fget (fil, line)))
%mend  readLine;

data _null_;
   fil = fopen('filref', 'i', , 'v');
   if fil = 0 then do;
      err = sysmsg();
      put "Could not open file";
      put  err;
   end;
   
/* Specify line feed (0x0A) as seperator so as to read to
   the end of a line: */
   %checkRC(%str(fsep(fil, 'a', 'x')))

/* Initialize the variable that will store the line read: */
   line = repeat(' ', 200);

/* Read the five lines in /tmp/tq84.txt: */
   %readLine put line;
   %readLine put line;
   %readLine put line;
   %readLine put line;
   %readLine put line;

/* Next readLine will cause
      Error with fread(fil)
      WARNING: End of file. */
   %readLine
run;
Github repository about-SAS, path: /programming/files/file-data-buffer/read-file.sas

Copy bytewise

/* 
  https://blogs.sas.com/content/sasdummy/2011/06/17/how-to-use-sas-data-step-to-copy-a-file-from-anywhere/
*/

x echo first line>   /tmp/tq84.src;
x echo second line>> /tmp/tq84.src;
x echo third line>>  /tmp/tq84.src;
x echo fourth line>> /tmp/tq84.src;

filename fil_src  '/tmp/tq84.src';
filename fil_dst  '/tmp/tq84.dst';

data _null_;
   fid_src = fopen('fil_src', 'i', 1, 'b'); 
   fid_dst = fopen('fil_dst', 'o', 1, 'b');
   rec = '.';
   do while (fread(fid_src)=0);
      rc=fget     (fid_src, rec, 1);
      rc=fput     (fid_dst, rec   );
      rc=fwrite   (fid_dst);
   end;
   rc=fclose(fid_src);
   rc=fclose(fid_dst);
run;
Github repository about-SAS, path: /programming/files/file-data-buffer/copy-bytewise.sas
See also Copy a file in a data step.

Index