Skip to content

Example Usage

Directory and File Manipulation

The .NET namespace System.IO (in the System.IO.FileSystem assembly) provides some useful facilities for manipulating files. For example, you can create a DirectoryInfo object associated with a particular directory on your computer, call its GetFiles method to obtain a list of files, and then get their Name and CreationTime properties:

      ⎕USING←,⊂'System.IO, System.IO.FileSystem'
      dir←'C:\Program Files\Dyalog\Dyalog APL-64 19.0 Unicode'
      d←⎕NEW DirectoryInfo (⊂dir)

where d is an instance of the Directory class, corresponding to the directory [DYALOG].

Information

[DYALOG] refers to the directory in which Dyalog is installed; this example assumes [DYALOG] to be C:/Program Files/Dyalog/Dyalog APL-64 19.0 Unicode.

The GetFiles method returns a list of files (more precisely, FileInfo objects) that represent each of the files in the directory. Its optional argument specifies a filter. For example:

      d.GetFiles ⊂'*.exe'
C:\Program Files\Dyalog\Dyalog APL-64 19.0 Unicode\dyaedit.exe  
C:\Program Files\Dyalog\Dyalog APL-64 19.0 Unicode\dyalog.exe  
C:\Program Files\Dyalog\Dyalog APL-64 19.0 Unicode\dyalogc.exe  
C:\Program Files\Dyalog\Dyalog APL-64 19.0 Unicode\dyalogc64_unicode.exe  
C:\Program Files\Dyalog\Dyalog APL-64 19.0 Unicode\dyalogrt.exe
  C:\Program Files\Dyalog\Dyalog APL-64 19.0 Unicode\dyascript.exe

The Name property returns the name of the file associated with the File object:

      (d.GetFiles ⊂'*.exe').Name
dyaedit.exe  dyalog.exe  dyalogc.exe  dyalogc64_unicode.exe  dyalogrt.exe  dyascript.exe

and the CreationTime property returns its creation time, which is a DateTime object:

     (d.GetFiles ⊂'*.exe').CreationTime
 08/02/2024 20:51:24  08/02/2024 20:50:06  08/02/2024 ...

Calling the GetFiles overload that does not take any arguments (from Dyalog by supplying an argument of ) returns a complete list of files:

      files←d.GetFiles ⍬
      files
C:\Program Files\Dyalog\Dyalog APL-64 19.0 Unicode\aplunicd.ini...

Taking advantage of namespace reference array expansion, an expression to display file names and their creation times is:

      files,[1.5]files.CreationTime
C:\...\...Unicode\aplunicd.ini               08/02/2024 20:12:02  
C:\...\...Unicode\bridge190-64_unicode.dll   08/02/2024 20:47:36  
...

Sending an Email

The .NET namespace System.Net.Mail provides objects for handing email. You can create a new email message as an instance of the MailMessage class, set its various properties and then send it using the SmtpClient class.

Example

This example will only work if your computer is configured to allow you to send email.

∇ recip Send(subject msg);⎕USING;from;mail;to;builder;client;
                                      FROM_ADDRESS; EMAIL_SERVER
  ⎕USING←'System.Net.Mail,System.Net.Mail'

  FROM_ADDRESS←'someone@somewhere.com'
  EMAIL_SERVER←'mail.somwhere.com'

  from←⎕NEW MailAddress(⊂FROM_ADDRESS)
  to←⎕NEW MailAddress(recip '')
  mail←⎕NEW MailMessage (from to)
  mail.Body←msg
  mail.Subject←subject
  client←⎕NEW SmtpClient (⊂EMAIL_SERVER)
  client.Send mail
∇

This could then be called as follows:

'prime.minister@gov.uk' Send ('subject' ('line1' 'line2'))

Web Scraping

.NET provides a range of classes for accessing the internet from a program. This section works through an example that shows how to read the contents of a web page. It is complicated, but realistic (for example, it includes code to cater for a firewall/proxy connection to the internet). It is only 9 lines of APL code, but each line requires careful explanation.

Start by defining ⎕USING so that it specifies all of the necessary .NET namespaces and assemblies:

      ⎕USING←,⊂'System,System.dll'
      ⎕USING,←⊂'System.Net, System.Net.Requests'
      ⎕USING,←⊂'System.IO'

The WebRequest class in the System.Net .NET namespace implements .NET's request/response model for accessing data from the internet. For this example, a WebRequest object needs to be associated with the URI http://www.dyalog.com (WebRequest is an example of a static class – its methods can be used without creating instances of it):

      wrq←WebRequest.Create ⊂'http://www.dyalog.com'

Potentially confusingly, if the URI specifies a protocol of "http://" or "https://", an object of type HttpWebRequest is returned rather than a simple WebRequest. The effect of this is that, at this stage, wrq is an HttpWebRequest object.

      wrq
System.Net.HttpWebRequest

The HttpRequest class has a GetResponse method that returns a response from an internet resource. Although it is not yet HTML, the result is an object of type System.Net.HttpWebResponse:

      wr←wrq.GetResponse
      wr
System.Net.HttpWebResponse

The HttpWebResponse class has a GetResponseStream method whose result is of type System.Net.ConnectStream. This object, whose base class is System.IO.Stream, provides methods to read and write data both synchronously and asynchronously from a data source, which in this case is physically connected to a TCP/IP socket:

      str←wr.GetResponseStream
      str
System.Net.Http.HttpConnection+ChunkedEncodingReadStream

However, the Stream class is designed for byte input and output; what is needed in this example is a class that reads characters in a byte stream using a particular encoding. This is a job for the System.IO.StreamReader class. Given a Stream object, create a new instance of a StreamReader by passing it the Stream as a parameter:

      rdr←⎕NEW StreamReader str
      rdr
System.IO.StreamReader

Finally, use the ReadToEnd method of the to get the contents of the page:

      s←rdr.ReadToEnd
      ⍴s
20295

Information

To avoid running out of connections, it is necessary to close the stream:

      str.Close