<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Copying binary files out of a ZIP fileref in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811430#M320045</link>
    <description>&lt;P&gt;I use code like this in a loop:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;/* Assign a fileref with the ZIP method */&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;filename inzip ZIP "&amp;amp;sourcedir/&amp;amp;&amp;amp;Name..zip";&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;/* Read Members from the zip file*/&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;data contents_tmp(keep=memname);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;length memname $200;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;fid=dopen("inzip");&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;if fid=0 then&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;stop;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;memcount=dnum(fid);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;do i=1 to memcount;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;memname=dread(fid,i);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;output;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;end;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;rc=dclose(fid);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;run;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;/* Append for each file to contents table */&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;PROC APPEND BASE=CONTENTS DATA=contents_tmp FORCE;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;RUN;&lt;/FONT&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;data xmlfiles_tmp(keep=File);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;length file $255.;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;File = "&amp;amp;sourcedir/&amp;amp;&amp;amp;Name..xml";&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;run;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;PROC APPEND BASE=XMLFILES DATA=xmlfiles_tmp FORCE;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;RUN;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;filename XML "&amp;amp;sourcedir/&amp;amp;&amp;amp;Name..xml";&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;data _null_;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;infile inzip(project.xml) &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;encoding = "UTF-16LE" &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;lrecl=2000&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;recfm=F &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;length=len &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;eof=eof unbuf&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;file XML lrecl=2000 recfm=N;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;input;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;put _infile_ $varying2000. len;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;return;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;eof:&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;stop;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;run;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 04 May 2022 12:58:51 GMT</pubDate>
    <dc:creator>Faruk</dc:creator>
    <dc:date>2022-05-04T12:58:51Z</dc:date>
    <item>
      <title>Copying binary files out of a ZIP fileref</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811409#M320037</link>
      <description>&lt;P&gt;I'm trying to unpack a ZIP file using FILENAME ZIP, similar to what was done in&amp;nbsp;&lt;A href="https://blogs.sas.com/content/sasdummy/2015/05/11/using-filename-zip-to-unzip-and-read-data-files-in-sas/" target="_self"&gt;this SAS Blog post&lt;/A&gt;. Ideally, I would like to handle the filerefs and the copy automatically inside a single data step using the FILENAME function (not statement) and FCOPY, but this gives problems with larger file sizes.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;As a reproducible example - note that I'm using a SAS dataset but the file type could be anything (the goal is to do a binary copy):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%let workdir = /path/to/workdir;

ods package open nopf;
ods package add file=".../path/to/sashelp/plfips.sas7bdat";
ods package publish archive properties(archive_path="&amp;amp;workdir" archive_name="data.zip");
ods package close;

options lrecl=max;

/* Does not work */
data _null_;
   length S $1024 FI FO $8 RC 8;
   
   rc = filename(FI, "&amp;amp;workdir./data.zip", "zip", "recfm=n member='plfips.sas7bdat'");
   rc = filename(FO, "&amp;amp;workdir./plfips.sas7bdat", "disk", "recfm=n");
   
   rc = fcopy(FI, FO);
   
   if rc ne 0 then do;
      s = sysmsg();
      put s;
   end;
   
   rc = filename(FI);
   rc = filename(FO);
run;&lt;BR /&gt;&lt;BR /&gt;WARNING: 0 records were truncated when the FCOPY function read from fileref #0000007.&lt;BR /&gt;         769 records were truncated when the FCOPY function wrote to fileref #LN00536.&lt;BR /&gt;         To prevent the truncation of records in future operations, you can increase the amount of space&lt;BR /&gt;         needed to accommodate the records by using the LRECL= system option or the LRECL= option in the FILENAME statement.&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;The resulting file is corrupted. SAS tells me to increase LRECL=, but this is already maximum and shouldn't come into play with RECFM=N.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Strangely enough, the following (more in line with the blog post) does work:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;/* Does work */

filename src ZIP  "&amp;amp;workdir./data.zip"        recfm=n;
filename tar DISK "&amp;amp;workdir./plfips.sas7bdat" recfm=n;

data _null_;
   infile src(plfips.sas7bdat);
   file tar;
   input;
   put _infile_;
run;

filename tar clear; /* flush the write */&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;However, apart from the use of FILENAME statements instead of functions I don't see the difference. Is there any way to make the first approach work correctly?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 04 May 2022 11:26:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811409#M320037</guid>
      <dc:creator>pblls</dc:creator>
      <dc:date>2022-05-04T11:26:48Z</dc:date>
    </item>
    <item>
      <title>Re: Copying binary files out of a ZIP fileref</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811416#M320041</link>
      <description>&lt;P&gt;I usually just use&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;recfm=f lrecl=512&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;when reading/writing/copying binary files.&lt;/P&gt;</description>
      <pubDate>Wed, 04 May 2022 11:56:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811416#M320041</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2022-05-04T11:56:17Z</dc:date>
    </item>
    <item>
      <title>Re: Copying binary files out of a ZIP fileref</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811430#M320045</link>
      <description>&lt;P&gt;I use code like this in a loop:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;/* Assign a fileref with the ZIP method */&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;filename inzip ZIP "&amp;amp;sourcedir/&amp;amp;&amp;amp;Name..zip";&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;/* Read Members from the zip file*/&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;data contents_tmp(keep=memname);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;length memname $200;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;fid=dopen("inzip");&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;if fid=0 then&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;stop;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;memcount=dnum(fid);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;do i=1 to memcount;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;memname=dread(fid,i);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;output;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;end;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;rc=dclose(fid);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;run;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;/* Append for each file to contents table */&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;PROC APPEND BASE=CONTENTS DATA=contents_tmp FORCE;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;RUN;&lt;/FONT&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;data xmlfiles_tmp(keep=File);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;length file $255.;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;File = "&amp;amp;sourcedir/&amp;amp;&amp;amp;Name..xml";&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;run;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;PROC APPEND BASE=XMLFILES DATA=xmlfiles_tmp FORCE;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;RUN;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;filename XML "&amp;amp;sourcedir/&amp;amp;&amp;amp;Name..xml";&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;data _null_;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;infile inzip(project.xml) &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;encoding = "UTF-16LE" &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;lrecl=2000&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;recfm=F &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;length=len &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;eof=eof unbuf&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;file XML lrecl=2000 recfm=N;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier" size="2"&gt;input;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;put _infile_ $varying2000. len;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;return;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;eof:&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;stop;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier" size="2"&gt;run;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 04 May 2022 12:58:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811430#M320045</guid>
      <dc:creator>Faruk</dc:creator>
      <dc:date>2022-05-04T12:58:51Z</dc:date>
    </item>
    <item>
      <title>Re: Copying binary files out of a ZIP fileref</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811438#M320051</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;&lt;P&gt;I usually just use&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;recfm=f lrecl=512&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;when reading/writing/copying binary files.&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Thanks! At first glance this seems to work in the FILENAME function as well, at least no more truncation warnings. It does appear that the file sometime gets padded though depending on the LRECL setting, and I see the following in the &lt;A href="https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/hostunx/n1epme0p3j1ueen1s38tjss396wn.htm" target="_self"&gt;unix&lt;/A&gt; documentation (not an issue on Windows but we use both):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;HR /&gt;Do not use RECFM=F for external files that contain carriage-control characters.&lt;/BLOCKQUOTE&gt;&lt;P class=""&gt;Would this not cause problems if the file being copied is an actual arbitrary binary stream? It was my impression that RECFM=N should make that a non-issue.&lt;/P&gt;</description>
      <pubDate>Wed, 04 May 2022 13:24:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811438#M320051</guid>
      <dc:creator>pblls</dc:creator>
      <dc:date>2022-05-04T13:24:39Z</dc:date>
    </item>
    <item>
      <title>Re: Copying binary files out of a ZIP fileref</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811769#M320224</link>
      <description>&lt;P&gt;Are you able to post your example?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;We use these macros for zipping / unzipping large folders with no issues:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://core.sasjs.io/mp__zip_8sas.html" target="_blank"&gt;https://core.sasjs.io/mp__zip_8sas.html&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://core.sasjs.io/mp__unzip_8sas.html" target="_blank"&gt;https://core.sasjs.io/mp__unzip_8sas.html&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 05 May 2022 22:35:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Copying-binary-files-out-of-a-ZIP-fileref/m-p/811769#M320224</guid>
      <dc:creator>AllanBowe</dc:creator>
      <dc:date>2022-05-05T22:35:05Z</dc:date>
    </item>
  </channel>
</rss>

