Getting Started with Java Console Applications using RemObjects C#

You can download a trial version of RemObjects C# with or without the required Visual Studio.

We have converted most of our Java console applications on the PPS website from Oxygene for Java to the RemObjects C# code shown on this page.

Page Contents

Output to the Console

Compare our first examples demonstrating output to the console with this original code. The code follows a screenshot of the output.

Output

using java.util;

namespace console_output_cs
  //converted from Oxygene for Java code at
  //http://www.pp4s.co.uk/main/tu-oxygene-console-output.html
{
  static class Program
  {
    public static void Main(string[] args)
    {
      Integer myInt = 42;
      Single mySingle = 1.2345;
      Char myChar = 'a';
      String myString = "Answer ";
      // Output one variable at a time.
      System.@out.println(myChar);
      System.@out.println(myInt);
      System.@out.println(mySingle);
      // Output a string composed of concatenated substrings.
      System.@out.println("Integer value " + myInt.toString());
      // Output a string and integer using printf.
      // %n creates a new line.
      System.@out.printf(myString + "%d%n", myInt);
      // Output a string and formatted float using printf.
      // (Can use console instead of out).
      System.@out.printf("Single value to 2 dp:%5.2f%n", mySingle);
      // Output a string containing more than one number.
      System.@out.printf("Integer value: %d%nSingle to 1 dp: %.1f%n",
                         myInt, mySingle);

      System.@in.read();
    }
  }
}

 

Input from the Keyboard Demo 1

This section is based on this Oxygene for Java page on our PPS site.

Keyboard input is achieved with the System.@in.read() method, which takes an array of SByte as its argument. You can convert this easily to a String; one of the constructors of a string takes an array of SByte as an argument followed by the index of the first SByte to convert then the length of the String. System.@in.read() returns the number of characters read, including the end of line marker(s). You do not usually wish to include these in your String. The expression System.lineSeparator().length() evaluates to 2 for Windows operating systems and 1 for Linux.

using java.util;

namespace keyboard_input1_cs
{
  static class Program
  {
    public static void Main(string[] args)
    {
      SByte[] inputBytes = new SByte[255];
      String myString;
      Integer inputLength;
      inputLength = System.@in.read(inputBytes);
      System.@out.println(inputLength);
      myString = new String(inputBytes, 0, inputLength -
                            System.lineSeparator().length());
      System.@out.println(myString);
      System.@in.read();
    }
  }
}

 

Input from the Keyboard Demo 2

You can use the above method to obtain a string to convert to a number using the valueOf() method of an Integer or Float. You may find it more convenient to supply a single argument to the String constructor then trim the String down to size, as in the following example. You need to be careful, however; the array of SByte is not automatically initialised upon reuse. Here we use a separate array for each input.

using java.util;

namespace keyboard_input2_cs
{
  static class Program
  {
    public static void Main(string[] args)
    {
      Integer myInt;
      Double myDouble;
      Char myChar;
      String strInt, strDouble;
      //Initialise arrays to prevent compiler warnings
      SByte[] intEntry = new SByte[12]{0,0,0,0,0,0,0,0,0,0,0,0};
      SByte[] doubleEntry = new SByte[20]
                              {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

      SByte[] charEntry = new SByte[3]{0,0,0};
      System.@out.println("Please enter an integer: ");
      System.@in.read(intEntry);
      strInt = new String(intEntry);
      myInt = Integer.valueOf(strInt.trim());
      System.@out.println("Your entry: " + myInt.toString());
      System.@out.println("Please enter a Double: ");
      System.@in.read(doubleEntry);
      strDouble = new String(doubleEntry);
      myDouble = Float.valueOf(strDouble.trim());
      System.@out.printf("Your entry to 3 places of decimals: %.3f%n",
                         myDouble);

      System.@out.println("Please enter a Char: ");
      System.@in.read(charEntry);
      myChar = chr(charEntry[0]);
      System.@out.println("Your entry: " + myChar);
      System.@in.read();
    }
  }
}

 

Input from the Keyboard Demo 3

For simplicity, the above demonstration code contains no validation. The following program shows an easy way to perform a type check on an Integer.

using java.util;

namespace keyboard_input3_cs
{
  static class Program
  {
    public static void Main(string[] args)
    {
      Integer myInt;
      String strInt;
      SByte[] currentEntry = new SByte[20];
      Boolean error = true;
      while (error)
      {
        error = false;
        System.@out.println("Please enter an integer: ");
        System.@in.read(currentEntry);
        strInt = new String(currentEntry);
        try
        {
          myInt = Integer.valueOf(strInt.trim());
        }
        catch(Exception E)
        {
          error = true;
        }
      }
      System.@out.println("Your entry: " + myInt.toString());
      System.@in.read();
    }
  }
}

 

Multiple Entry

The code below, which follows a screenshot, shows how to input multiple items of data of the same type, separated by a space. Method MultipleEntry() reads three integers and finds their mean. If you want to read more than a line at a time, read each character as shown in method EnterLines().

Output

using java.util;

namespace multiple_entry_cs
{
  static class Program
  {
    public void MultipleEntry()
    {
      SByte[] inputNums = new SByte[255];
      Single mean;
      Integer int1, int2, int3;
      String strInt1, strInt2, strInt3;
      Integer count = 0;
      strInt1 = "";
      strInt2 = "";
      strInt3 = "";
      System.@out.println("Please enter three integers" +
                          "separated by spaces.");
      System.@in.read(inputNums);

      while (inputNums[count] != 32)
      {
        strInt1 = strInt1 + chr(inputNums[count]);
        inc(count);
      }
      inc(count);
      while (inputNums[count] != 32)
      {
        strInt2 = strInt2 + chr(inputNums[count]);
        inc(count);
      }
      inc(count);
      while (inputNums[count] != 13)
      {
        strInt3 = strInt3 + chr(inputNums[count]);
        inc(count);
      }
      int1 = Integer.valueOf(strInt1);
      int2 = Integer.valueOf(strInt2);
      int3 = Integer.valueOf(strInt3);
      mean = (int1 + int2 + int3) / 3.0;  //3.0 not 3
      System.@out.println();
      System.@out.printf("Their mean is %.2f", mean);
      System.@out.println();
    }

    public void Enterlines()
    {
      const Integer MAX_CHARS = 1000;
      Integer lineCount, totalChars;
      SByte[][] lines = new SByte[9][];
      for (int i = 0; i < 9; i++)
      {
        lines[i] = new SByte[255];
      }
      SByte[] currentLine = new SByte[255];
      Integer[] lineLengths = new Integer[9];
      Char[] characters = new Char[MAX_CHARS - 1] ;

      totalChars = 0;
      lineCount = 0;
      System.@out.println("Please enter several lines of text (# on " +
                          "a new line then Enter to finish).");
      System.@out.println();
      while (lines[lineCount][0] != 35) //while first char in line not #
      {
        if (lineCount > 0)
          inc(lineCount);
        lineLengths[lineCount] = System.@in.read(currentLine);
        lines[lineCount] = currentLine;
        for (Integer i = 0 ; i <= lineLengths[lineCount]; i++)
        {
          characters[totalChars + i] = chr(lines[lineCount][i]);
        }
        totalChars += lineLengths[lineCount];
      }
      System.@out.println();
      System.@out.println("ASCII values recorded (with each new line" +
                          "represented by 13 & 10 (Win) or 10 (Linux)");
      System.@out.println();
    
      for (Integer i = 0; i < totalChars; i++)
      {
        write(ord(characters[i]).toString() + " ");
      }
      System.@out.println();
    }

    public static void Main(String[] args)
    {
      MultipleEntry();
      Enterlines();
      System.@in.read();
    }
  }
}

 

File Handling

The next three programs are converted from these Oxygene demonstrations.

Using Text Files

If you just need to save lines of text to file and be able to read them, you can achieve this fairly simply with a PrintWriter, FileReader and LineNumberReader as follows.

using java.util;
using java.io;

namespace lines_of_text_cs
{
  static class Program
  {
    public static void Main(string[] args)
    {
      String[] myStrings = new String[10];
      PrintWriter pw;
      FileReader fr;
      LineNumberReader lnr;
      pw = new PrintWriter("test.txt");
      for (int i = 1; i <= 10; i++)
      {
        pw.println("line " + i.toString());
      }
      pw.close();
      fr = new FileReader("test.txt");
      lnr = new LineNumberReader(fr);
      for (int i = 0; i <= 9 ; i++)
      {
        myStrings[i] = lnr.readLine();
      }
      fr.close();   
      for (int i = 0 ; i <= 9; i++)
      {
        System.@out.println(myStrings[i]);
      }
      System.@in.read();
    }
  }
}

 

Using Random Access Files

For other tasks, we recommend the use of a RandomAccessFile. This handles the common file types and has writeUTF() and readUTF() methods to write and read strings. The length of each string accompanies the characters, obviating the need for separators such as end of line markers. You can use the seek() method to locate the end of the file in order to append data. Open the file for reading and writing ("rw") to write and for reading only ("r") to read.

using java.util;
using java.io;

namespace random_access
{
  static class Program
  {
    public static void Main(string[] args)
    {
      RandomAccessFile raf;
      String line = "";
      String  myString;
      Char myChar;
      Float myFloat;
      Integer myInt;
      Int64 myInt64;
      String Eoln  = System.lineSeparator();
      // Create random access file and write to it 3 line-terminated
      // Strings, then String, Char, Float, Int and Int64.
      raf = new RandomAccessFile("test.txt", "rw");
      raf.writeBytes("We use the writeBytes method to " +  
                     "write our strings," + Eoln);
      raf.writeBytes("and then the line separator." + Eoln);
      raf.writeBytes("We can then read each string using the " +
                     "readline method." + Eoln);
      raf.writeUTF("This can be any length and does not end" +
                    "with a new line.");
      raf.writeChar('a');
      raf.writeFloat(3.12156);
      raf.writeInt(123);
      raf.writeLong(10000000);
      raf.close();
      //Open random access file for reading and read from it
      //3 Strings and output them.
      raf = new RandomAccessFile("test.txt", "r");
      for (Integer i = 1; i <= 3; i++)
      {
        line = raf.readLine();
        System.@out.println(line);
      }
      //Read String, Char, Float, Int and Int64.
      myString = raf.readUTF();
      myChar = raf.readChar();
      myFloat = raf.readFloat();
      myInt = raf.readInt();
      myInt64 = raf.readLong();
      //Output values of Float, Int and Int64.
      System.@out.println("String: " + myString);
      System.@out.println("Single character read from file: " + myChar);
      System.@out.println("Float read from file: " + myFloat.toString());
      System.@out.println("Integer read from file: " + myInt.toString());
      System.@out.println("Int64 read from file: " + myInt64.toString());
      raf.close();
      System.@in.read();
    }            
  }
}

 

Saving and Loading Records represented as Objects

The next demonstration shows how you can write and read variable length records. An object consisting of fields and no methods is a record.

using java.util;
using java.io;

namespace random_access2_cs
{  
  class ageRecord
  {
    public String surname;
    public Integer age;
  }

  static class Program
  {
    private
      ageRecord[] ageRecords = new ageRecord[3];
      ageRecord[] ageRecs = new ageRecord[3];
    public static void Main(string[] args)
    {
      RandomAccessFile  raf;
      ageRecords[0] = new ageRecord();
      ageRecords[0].surname = "Shah";
      ageRecords[0].age = 16;
      ageRecords[1] = new ageRecord();
      ageRecords[1].surname = "Ennis";
      ageRecords[1].age = 22;
      ageRecords[2] = new ageRecord();
      ageRecords[2].surname = "Biggs";
      ageRecords[2].age = 55;
      raf = new RandomAccessFile("test.txt", "rw");
      for (Integer i = 0; i <= 2; i++)
      {
        raf.writeUTF(ageRecords[i].surname);
        raf.writeInt(ageRecords[i].age);
      }
      raf.close();
      //Open random access file for reading and read 3 records from it.
      raf = new RandomAccessFile("test.txt", "r");
      for (Integer i = 0; i <= 2; i++)
      {
        ageRecs[i] = new ageRecord();
        ageRecs[i].surname = raf.readUTF();
        ageRecs[i].age = raf.readInt();
      }
      raf.close();
      for (Integer i = 0; i <= 2; i++)
      {
        System.@out.print(ageRecs[i].surname + ": ") ;
        System.@out.println(ageRecs[i].age);
      }
      System.@in.read();
    }    
  }
}

 

Reading a file on the web

We use a URL object for the download, and read it with an InputStreamReader and BufferedReader. The example shows the reading of a short html file on the PPS website.

A URLConnection object offers further methods and the example shows the reading of a few lines of header data that accompany the above file download.

You can see a screenshot and compare the code below with the Oxygene original on this PPS page.


using java.util;
using java.net;
using java.io;

namespace web_doc_cs
{
  static class Program
  {
    private
      URL u;
      URLConnection conn;
      String fieldname, value;
      BufferedReader br;  
      InputStreamReader isr;
      String currentLine  = "";

    public void ReportError(Exception E)
    {
      System.@out.println(E.toString());
      System.@in.read();
      System.exit(0);
    }

    public void Main(string[] args)
    {
      try
      {
        u = new URL(
        "http://www.pp4s.co.uk/static/pp4s/resources/RunPenApplet.html");
        isr = new InputStreamReader(u.openStream());
        br = new BufferedReader(isr);
        currentLine = br.readLine();
        while (currentLine != null)
        {
          System.@out.println(currentLine);
          currentLine = br.readLine();
        }
      }
      catch(Exception E)
      {
        ReportError(E);
      }

      try
      {
        conn = u.openConnection();  
        for (Integer i  = 1 ; i <= 6; i++)
        {
          fieldname = conn.getHeaderFieldKey(i);
          value  = conn.getHeaderField(i);
          System.@out.println(fieldname + " " + value);
        }
      }
      catch(Exception E)
      {
        ReportError(E);
      }
      System.@in.read();
      System.@in.read();
    }
  }
}

 

Echo Server with new Thread for each new Client

We ported this code from our original Oxygene version.


using java.util;
using java.io;
using java.net;

namespace echo_server03cs
{
  public void ReportError(Exception E)
  {
    System.@out.println (E.toString());
    System.@in.read();
    System.exit(0);
  }

  public class ConnectionHandler: Runnable
  {
    private Socket cs = null;
    private PrintWriter pw = null;
    private BufferedReader br = null;
    private InputStreamReader isr = null;
    private String msg ="";
    public ConnectionHandler(Socket s)
    {
      cs = s;
      try
      {    
        isr = new InputStreamReader(cs.getInputStream());
        br = new BufferedReader(isr);
        pw = new PrintWriter(cs.getOutputStream(), true);
      }
      catch(Exception E)
      {
        ReportError(E);
      }  
    }

    public void run()
    {
      while ((msg != "end") && (msg != "quit"))
      {
        msg = br.readLine();
        if ((msg != "quit") && (msg != "end"))
        {
          pw.println(msg);
          System.@out.println("Echoing " + msg);  
        }
      }
      pw.close();
      isr.close();
      br.close();
      cs.close();
      if (msg == "quit")
        System.exit(0);
      
    }
  }

  static class Program
  {
    public static void Main(string[] args)
    {
      const Integer  MAX_CLIENTS = 5;
      const Integer SERVER_PORT = 1718;
      ServerSocket  serverSocket = null;
      Socket  clientSocket = null;
      ConnectionHandler connectionHandler;
      Thread t;
      try
      {
        serverSocket = new ServerSocket(SERVER_PORT, MAX_CLIENTS);
      }
      catch(Exception E)
      {
        ReportError(E);
      }   
      System.@out.println("Waiting");    
      while(true)
      {
        try
        {
          clientSocket = serverSocket.accept();
        }

        catch(Exception E)
        {
          ReportError(E);
        }

        connectionHandler = new ConnectionHandler(clientSocket);
        t = new Thread(connectionHandler);
        t.start();    
      }
    }
  }
}

 

Echo Client

using java.util;
using java.io;
using java.net;

namespace echo_client03cs
{
  static class Program
  {
    public static void Main(string[] args)
    {
      const Integer SERVER_PORT = 1718;
      String sourceString, echoedString, ip_string;
      PrintWriter pw = null;
      BufferedReader br = null;
      InputStreamReader isr = null;
      Socket clientSocket = null;
      SByte[] ip = new SByte[20]; //ip[0] .. ip[19]
      SByte[] msg = new SByte[20];
      sourceString ="";
      System.@out.println("Please enter IP address of server" +
                          " (127.0.0.1 for same machine as client).");
      System.@in.read(ip);
      ip_string = new String(ip).trim();
      try
      {
        clientSocket = new Socket(InetAddress.getByName(ip_string),
                                  SERVER_PORT);

        pw = new PrintWriter(clientSocket.getOutputStream(), true);
        isr = new InputStreamReader(clientSocket.getInputStream());  
        br = new BufferedReader(isr);
      }

      catch(Exception E)
      {
        System.@out.println(E.toString());
        System.@in.read();
        System.exit(0);        
      }
    
      while ((sourceString != "quit") && (sourceString != "end"))
      {
        System.@out.println("Please enter short string to be echoed.");
        System.@out.println("Enter quit to quit the server and " +
                       "end to quit the client.");
        msg = {32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
               32, 32, 32, 32, 32, 32, 32, 32, 32, 32};

        System.@in.read(msg);
        sourceString = new String(msg).trim();
        pw.println(sourceString);
        if ((sourceString != "quit") && (sourceString != "end"))
        {
          echoedString = br.readLine();
          System.@out.println("The echoed string " + echoedString);
        }
      }  
      pw.close();
      br.close();
      isr.close();
      clientSocket.close();
    }
  }
}

 

Accessing Data in a Firebird Database

We give detailed instructions in the PPS database tutorial for getting started with Firebird and for creating and populating the CONTRIBUTIONS.MDB Firebird database. In order to access it from a RemObjects C# program, you need a reference to the unzipped jaybird-full-2.2.5.jar from the JDBC driver download. (The Java 7 version worked for us).

To add the reference:

  1. right click on References in the Solution Explorer of Visual Studio then select the menu option Add Reference;
  2. click on the Browse button at the bottom of the new window;
  3. navigate to the required jar file jaybird-full-2.2.5.jar;
  4. double click on the filename;
  5. click the OK button.

This snippet is copied from the .hydrogene project file:

  <ItemGroup>
    <Reference Include="jaybird-full-2.2.5.jar">
      <HintPath>..\..\..\..\Jaybird\jaybird-full-2.2.5.jar</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="rt.jar" />
  </ItemGroup>

This RemObjects C# code accesses a copy of CONTRIBUTIONS.FDB in the root of the F drive.

using java.util;
using java.sql;  

namespace FirebirdTestCS
{
  static class Program
  {
    public static void Main(string[] args)
    {
      Connection conn = null;
      ResultSet rs = null;
      Statement st = null;
      try
      {
        @Class.forName("org.firebirdsql.jdbc.FBDriver");
        conn = DriverManager.getConnection(  
               "jdbc:firebirdsql://localhost:3050/F:/CONTRIBUTIONS.FDB",  
               "student", "pp4s");
        st = conn.createStatement();  
        rs = st.executeQuery("SELECT Forename FROM Programmer" +
                             " ORDER BY Forename");
        System.@out.println("Forenames of contributors" +
                            " in alphabetical order:" );
        while (rs.next())
        {
          System.@out.println(rs.getString("Forename"));
        }
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
      finally
      {
        try
        {
          rs.close();  
          st.close();  
          conn.close();
        }
        catch(Exception e)
        {
          e.printStackTrace();
        }
      }      
      System.@in.read();
    }
    }
}