FileIO Demo (NiceToolkit)

by Erick Engelke
September 2, 2042

This description is only helpful if you purchase my Nice Toolkit for EWB

The Nice Toolkit adds many features to EWB, including many graphical features, but also the ability to read and write files directly into or from the browser, no server code required.

Imagine being able to ask for a Jpeg or Png of a user, and being able to place that into a TDataSet string which can immediately be used to populate a TImage, or a PDF which can populate a TBrowser component, and save to your server.

Likewise, if desireable, you can save Binary (such aas Images) or Text files directly to the local device. By rules of the Browser, these files will always go into the Downloads (or similar) directory.

These file operations are faster and less cumbersome than using a typical EWB solution of THTMLForm and uploading to the server and then downloading again. They will make your application seem more powerful.

You can also use this to upload chuncks, eg. 64 kB at a time, to the server, giving feedback about the upload to your user. For large video files, like YouTube, this makes sense since uploads are often slower than downloads.

The following demo, with about 60 lines of actual Object Pascal, can read PNG, Jpeg, and PDF files from the local computer, display them, and let you resave them to the local system. See the demo in action here.

unit filedemounit;

interface

uses WebCore, webdom, WebUI, WebForms, WebCtrls, WebEdits, WebBrwsr, WebBtns, fileio, niceexception, WebLabels,
     WebComps, WebCtnrs;

type

   TForm1 = class(TForm)
      FileComboBox1: TFileComboBox;
      Button1: TButton;
      lbFileType: TLabel;
      lbHelp: TLabel;
      lbAsFilename: TLabel;
      Edit1: TEdit;
      ScrollPanel1: TScrollPanel;
      Browser1: TBrowser;
      lbEncoding: TLabel;
      Image1: TImage;
      procedure Button1Click(Sender: TObject);
      procedure Form1Show(Sender: TObject);
   private
      { Private declarations }
      io : TFileIO;
      mimetype : string;
      data : variant;
      procedure onreadload( x : variant );
      procedure LoadScriptSuccess( sender :TObject);
      procedure LoadScriptError( sender :TObject);
   public
      { Public declarations }
   end;

var
   Form1: TForm1;

implementation

procedure TForm1.LoadScriptSuccess( sender : TObject );
begin
  //
end;


procedure TForm1.LoadScriptError( sender : TObject );
begin
  showmessage('Unable to load filesaver, file saving will not work!'+#13+ TScript( sender ).URL );
end;

procedure TForm1.onreadload( x : variant );
var
   mime : TMime;
   ext : string;
   i : integer;
begin
   Browser1.URL := x ;
   image1.url := x;

   // look to see what type of file it is
   mime := mime_decode( x );
   data := mime.data;
   mimetype := mime.mimetype;
   lbFiletype.Caption := 'File type: ' + mimetype;
   lbEncoding.Caption := 'Encoding: ' + mime.encoding;

   i := pos('/', mimetype );
   if i > 0 then begin
      ext := '.'+copy( mimetype, i+1 );

      edit1.Text := ChangeFileExt( edit1.Text, ext );
   end;
end;


procedure TForm1.Form1Show(Sender: TObject);
begin
   if isie then begin
      Showmessage('This program does not work under Internet Explorer, use an HTML5 browser like Chrome, Firefox, Safari, etc.');
   end;
   SetupNiceExceptionHandling;
   io := TFileIO.Create( self );

   // next three lines load the filesaver API
   io.scriptfilesaver.OnError := LoadScriptError;
   io.scriptfilesaver.OnLoad := LoadScriptSuccess;
   io.LoadFileSaver;

   io.setupfilecombobox( FileComboBox1, onreadload );
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   io.FileSaveAs( Edit1.Text, mimetype , data );
end;

end.

Here’s how it works.

Form1Show

Form1Show() warns if Internet Explorer is being used. IE is several years out of date, not HTML5 compliant, and never will be since it is a discontinued product. EWB uses IE as its browser with the GUI, so this demo will not work in the IDE.

SetupNiceExceptionHandling just gives us much more informative error messages if an exception is raised. It will usually tell which line of JavaScript was the offending command.

io := TFileIo.Create(…​ is used to create the background form which loads the necessary libraries to make this all work.

io.scriptfilesaver.OnError and OnLoad are just routines which will be called once the library is loaded or fails.

Then io.LoadFileSaver() loads the library as needed.

io.setupfilecombobox(…​) configures the TFileComboBox to immediately being an upload to the browser, calling onReadLoad() with the new file details.

onreadload( x : variant );

This routine is upcalled when new file data is availaable.

Browser1 and image1 can directly handle the data object. And you can save it as a (very long) string to your TDataSet string fields.

Next we look to decode the Mime information, such as what is the data, what is the encoding (eg. Base64), and what is the mime-type which tells us if it is a PNG, Jpeg, PDF, Text, etc.

Finally, we look up the extension from the mime type, and use it to set the filename extension of the suggested sample file for saving.

Button1Click

Saving data to a file couldn’t be much easier.

We save data (which is a binary blob) to Edit1.Text as a filename, with the specified mimetype we learned from the upload.

   io.FileSaveAs( Edit1.Text, mimetype , data );

If we wanted to save some text, we could use

   io.FileSaveAx('myfile.txt','text/plain','blah blah blah'+#13+#10 );

Download

Here’s a link to the project zip file. You will need the latest version of Nice Library, it was updated September 3, 2024.

Summary

Almost anything you could do in JavaScript can be done with EWB. And with tools like file i/o, the difference between a so-called desktop application and a browser page are becoming less clear-cut.