Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Wednesday, February 22, 2012

Java 7 new features - 9. Fork/Join : CDR Loading example


<< Previous Table of Categories


In the telecommunication environment, CDR(Call Detail Record) files are widely used. It is very important to load CDR files efficiently. Fortunately, the fork/join framework helps developers take advantage of multiple processors which are used in almost every server.
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class CDRLoadingForkJoin
    extends RecursiveAction
{
    static final int FILE_COUNT_THRESHOLD = 1;
    File[] cdrFiles = null;

    public CDRLoadingForkJoin(File[] cdrFiles)
    {
        this.cdrFiles = cdrFiles;
    }

    @Override
    protected void compute()
    {
        try
        {
            // Check the number of files
            if (cdrFiles.length <= FILE_COUNT_THRESHOLD)
            {
                loadCDRFiles(cdrFiles);
            }
            else
            {
                // Split the array of CDR files into two equal parts
                int center = cdrFiles.length / 2;
                File[] part1 = splitArray(cdrFiles, 0, center);
                File[] part2 = splitArray(cdrFiles, center, cdrFiles.length);
                invokeAll(new CDRLoadingForkJoin(part1), new CDRLoadingForkJoin(part2));
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    protected File[] splitArray(File[] array, int start, int end)
    {
        int length = end - start;
        File[] part = new File[length];
        for (int i = start; i < end; i++)
        {
            part[i - start] = array[i];
        }
        return part;
    }

    protected void loadCDRFiles(File[] filesToLoad)
    {
        for (File file: filesToLoad)
        {
            if (file.getName().endsWith(".cdr"))
            {
                try
                {
                    BufferedReader reader = new BufferedReader(new FileReader(file));
                    String line = null;
                    while ((line = reader.readLine()) != null)
                    {
                        //load to database ..
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

    // Start the CDR file loading process with the Java SE 7 Fork/Join framework
    public static void main(String[] args)
    {
        String cdrDirPath = "D:\\CDR\\";
        File cdrDir = new File(cdrDirPath);
        if(!cdrDir.isDirectory())
        {
            System.err.println(cdrDirPath + " is not a valid directory");
        }
        File[] files = cdrDir.listFiles();
        CDRLoadingForkJoin process = new CDRLoadingForkJoin(files);
        int processors = Runtime.getRuntime().availableProcessors();
        ForkJoinPool pool = new ForkJoinPool(processors);
        pool.invoke(process);
    }
}

Tuesday, February 7, 2012

Java 7 new features - 8. NIO2 : F. Review - Traditional TCP server/client example


<< Previous Table of Categories Next >>


After we learnt how the NIO2 works, let's review the traditional socket programming
Traditional TCP Server
 
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class TraditionalTcpSocketServer
{
    public static void main(String[] argv)
        throws Exception
    {
        String clientSentence;
        ServerSocket welcomeSocket = new ServerSocket(9001);
        while (true)
        {
            Socket connectionSocket = welcomeSocket.accept();
            BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
            DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
            clientSentence = inFromClient.readLine();
            System.out.println("FROM CLIENT: " + clientSentence);
            outToClient.writeBytes("World" + System.getProperty("line.separator"));
        }
    }
}
Traditional TCP Client
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class TraditionalTcpSocketClient
{
    public static void main(String[] argv)
        throws Exception
    {
        String sentence = "Hello";
        String modifiedSentence;
        Socket clientSocket = new Socket("localhost", 9001);
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        outToServer.writeBytes(sentence + System.getProperty("line.separator"));
        modifiedSentence = inFromServer.readLine();
        System.out.println("FROM SERVER: " + modifiedSentence);
        clientSocket.close();
    }
}

Monday, February 6, 2012

Java 7 new features - 7. NIO2 : E. Asynchronous TCP server/client example


<< Previous Table of Categories Next>>


To illustrate how Asynchronous works, there are some delay in both the server and the client. You can easily play this on your PC to understand how the Asynchronous channels work.
Asynchronous TCP Server
 
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class AsynchronousTcpServer
{
    public static void main(String[] args)
    {

        final int SERVER_PORT = 9001;
        final String SERVER_IP = "127.0.0.1";

        //create asynchronous server-socket channel bound to the default group
        try (AsynchronousServerSocketChannel asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open())
        {
            if (asynchronousServerSocketChannel.isOpen())
            {
                //bind to local address
                asynchronousServerSocketChannel.bind(new InetSocketAddress(SERVER_IP, SERVER_PORT));

                //display a waiting message 
                System.out.println("Waiting for connections ...");
                while (true)
                {
                    Future<AsynchronousSocketChannel> asynchronousSocketChannelFuture =
                        asynchronousServerSocketChannel.accept();
                    try (AsynchronousSocketChannel asynchronousSocketChannel = asynchronousSocketChannelFuture.get())
                    {
                        System.out.println("Incoming connection from: " + asynchronousSocketChannel.getRemoteAddress());
                        ByteBuffer incomingBuffer = ByteBuffer.allocateDirect(1024);
                        //receiving data
                        asynchronousSocketChannel.read(incomingBuffer, incomingBuffer,  new CompletionHandler<Integer, ByteBuffer>()
                        {
                            public void completed(Integer result, ByteBuffer buffer)
                            {
                                buffer.flip();
                                String msgReceived = Charset.defaultCharset().decode(buffer).toString();
                                System.out.println("Msg received from the client : " + msgReceived);
                            }
                            public void failed(Throwable exc, ByteBuffer buffer)
                            {
                                throw new UnsupportedOperationException("read failed!");
                            }                                             
                        });
                        try
                        {
                            Thread.sleep(5000);
                        }
                        catch(Exception e){}
                        
                        //replying data
                        ByteBuffer outgoingBuffer = ByteBuffer.wrap("World".getBytes());
                        asynchronousSocketChannel.write(outgoingBuffer).get();
                    }
                    catch (IOException | InterruptedException | ExecutionException ex)
                    {
                        System.err.println(ex);
                    }
                }
            }
            else
            {
                System.out.println("The asynchronous server-socket channel cannot be opened!");
            }
        }
        catch (IOException ex)
        {
            System.err.println(ex);
        }
    }
}
Asynchronous TCP Client
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutionException;

public class AsynchronousTcpClient
{
    static boolean completed = false;
    public static void main(String[] args)
    {
        
        final int SERVER_PORT = 9001;
        final String SERVER_IP = "127.0.0.1";
       
        ByteBuffer receivingBuffer = ByteBuffer.allocateDirect(1024);
        ByteBuffer sendingBuffer = ByteBuffer.wrap("Hello".getBytes());
               
        //create asynchronous socket channel
        try (final AsynchronousSocketChannel asynchronousSocketChannel = AsynchronousSocketChannel.open())
        {
            if (asynchronousSocketChannel.isOpen())
            {
                //connect this channel's socket
                Void connect = asynchronousSocketChannel.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT)).get();
                if (connect == null)
                {
                    System.out.println("Local address: " + asynchronousSocketChannel.getLocalAddress());
                    
                    //sending data
                    asynchronousSocketChannel.write(sendingBuffer).get();
                    asynchronousSocketChannel.read(receivingBuffer, receivingBuffer,  new CompletionHandler<Integer, ByteBuffer>()
                    {
                        public void completed(Integer result, ByteBuffer buffer)
                        {
                            buffer.flip();
                            String msgReceived = Charset.defaultCharset().decode(buffer).toString();
                            System.out.println("Msg received from server : " + msgReceived);
                            completed = true;
                        }
                        public void failed(Throwable exc, ByteBuffer buffer)
                        {
                            completed = false;
                            throw new UnsupportedOperationException("read failed!");
                        }                                             
                  });
                  
                  while(!completed)
                  {
                      try
                      {
                          Thread.sleep(1000);
                      }
                      catch(Exception e){}
                      System.out.println("Waiting for response from the server");
                  } 
                  
                }
                else
                {
                    System.out.println("The connection cannot be established!");
                }
            }
            else
            {
                System.out.println("The asynchronous socket channel cannot be opened!");
            }
        }
        catch (IOException | InterruptedException | ExecutionException ex)
        {
            System.err.println(ex);
        }
      
    }
}

Monday, January 30, 2012

Java 7 new features - 6. NIO2 : D. Non Blocking TCP server/client example


<< Previous Table of Categories Next>>


To illustrate how non-blocking works, the server will sleep for 1 second. You can understand this better by runing thest two classes and check the log messages
Non Blocking TCP Server
 
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;

public class NonBlockingTcpServer
{    
    public static void main(String[] args) throws Exception
    {
        final int DEFAULT_PORT = 9001;
        ByteBuffer incomingBuffer = ByteBuffer.allocateDirect(1024);
        Charset charset = Charset.defaultCharset();
        CharsetDecoder decoder = charset.newDecoder();
        ByteBuffer outgoingBuffer = ByteBuffer.wrap("World".getBytes());
    
        //Open Selector and ServerSocketChannel
        try (Selector selector = Selector.open();
             ServerSocketChannel serverSocketChannel = ServerSocketChannel.open())
        {
            //Check if both of them were opened
            if ((serverSocketChannel.isOpen()) && (selector.isOpen()))
            {
                //Configure non-blocking mode
                serverSocketChannel.configureBlocking(false);
                //Bind to the specific port number
                serverSocketChannel.bind(new InetSocketAddress(DEFAULT_PORT));
                //Register the current channel with the given selector
                serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            
                System.out.println("Waiting for incoming connections ...");
                while (true)
                {
                    //wait for incomming events
                    selector.select();
                    //there is something to process on selected keys
                    Iterator keys = selector.selectedKeys().iterator();
                    while (keys.hasNext())
                    {
                        SelectionKey key = (SelectionKey) keys.next();
                        //prevent the same key from coming up again
                        keys.remove();
                        if (!key.isValid())
                        {
                            continue;
                        }
                        //Accept incoming connection
                        if(key.isAcceptable())
                        {
                            ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
                            SocketChannel socketChannel = serverChannel.accept();
                            socketChannel.configureBlocking(false); 
                            System.out.println("Accept incomming connection from: " + socketChannel.getRemoteAddress());
                            socketChannel.register(selector, SelectionKey.OP_READ);
                        }
                        if (key.isReadable())
                        {
                            SocketChannel socketChannel = (SocketChannel) key.channel();
                            incomingBuffer.clear();
                            int numRead = -1;
                            try
                            {
                                numRead = socketChannel.read(incomingBuffer);
                            }
                            catch (Exception e)
                            {
                                e.printStackTrace();
                                key.cancel();
                                continue;
                            }
                            incomingBuffer.flip();
                            String requestMsg = decoder.decode(incomingBuffer).toString();
                            System.out.println("Request from " + socketChannel.getRemoteAddress() + " : " + requestMsg);
                            Thread.sleep(1000);
                            socketChannel.write(outgoingBuffer);
                            outgoingBuffer.flip();
                            socketChannel.shutdownOutput();
                            key.cancel();
                        }
                    }
                }
            }
            else
            {
                System.out.println("The server socket channel or selector cannot be opened!");
            }
        }
        catch (IOException ex)
        {
            System.err.println(ex);
        }
    }
}

Non Blocking TCP Client
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;

public class NonBlockingTcpClient
{
    public static void main(String[] args)
    {
        final int DEFAULT_PORT = 9001;
        final String IP = "127.0.0.1";
        ByteBuffer receivingBuffer = ByteBuffer.allocateDirect(1024);
        ByteBuffer sendingBuffer = ByteBuffer.wrap("Hello".getBytes());
        Charset charset = Charset.defaultCharset();
        CharsetDecoder decoder = charset.newDecoder();
        String responseMsg = "";
        //open Selector and ServerSocketChannel
        try (Selector selector = Selector.open();
             SocketChannel socketChannel = SocketChannel.open())
        {
            //check that both of them were opened
            if ((socketChannel.isOpen()) && (selector.isOpen()))
            {
                //configure non-blocking mode
                socketChannel.configureBlocking(false);
                //register the current channel with the given selector
                socketChannel.register(selector, SelectionKey.OP_CONNECT);
                socketChannel.connect(new java.net.InetSocketAddress(IP, DEFAULT_PORT));

                //waiting for the connection
                while(selector.select(1000) > 0)
                {
                    //get keys
                    Set keys = selector.selectedKeys();
                    Iterator its = keys.iterator();
                    //process each key
                    while (its.hasNext())
                    {
                        SelectionKey key = (SelectionKey) its.next();
                        //remove the current key
                        its.remove();
                        //get the socket channel for this key
                        try (SocketChannel keySocketChannel = (SocketChannel) key.channel())
                        {
                            //attempt a connection
                            if (key.isConnectable())
                            {
                                //make sure the connection estqablishment has been finished
                                if (keySocketChannel.isConnectionPending())
                                {
                                    keySocketChannel.finishConnect();
                                }
                                keySocketChannel.write(sendingBuffer);
                                keySocketChannel.shutdownOutput();
                                long startTime = System.currentTimeMillis();
                                while (keySocketChannel.read(receivingBuffer) != -1)
                                {
                                    long elapsedTime = System.currentTimeMillis() - startTime;
                                    System.out.println("elapsedTime=" + elapsedTime);
                                    receivingBuffer.flip();
                                    String msgReceived = decoder.decode(receivingBuffer).toString();
                                    System.out.println("Msg received in this loop : " + msgReceived);
                                    responseMsg = responseMsg + msgReceived;
                                    if (receivingBuffer.hasRemaining())
                                    {
                                        receivingBuffer.compact();
                                    }
                                    else
                                    {
                                        receivingBuffer.clear();
                                    }
                                }
                                System.out.println("Response from server : " + responseMsg);
                            }
                            else
                            {
                                System.out.println("The connection cannot be established!");   
                            }
                        }
                        catch (IOException ex)
                        {
                            System.err.println(ex);
                        }
                    }
                }
            }
            else
            {
                System.out.println("The socket channel or selector cannot be opened!");
            }
        }
        catch (IOException ex)
        {
            System.err.println(ex);
        }
    }
}

Monday, January 16, 2012

Java 7 new features - 5. NIO2 : C. Blocking TCP server/client example


<< Previous Table of Categories Next>>


Java 7 introduces a new interface - NetworkChannel that provides common methods to all network channel classes and a new SocketOption interface and StandardSocketOptions class. Please check the following exmaple. To demonstrate how ByteBuffer works, I just set buffer size as 2.

Blocking TCP Server
 
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

public class BlockingTcpServer
{
    public static void main(String[] args)
    {
        final int SERVER_PORT = 9001;
        final String SERVER_IP = "127.0.0.1";
        
        ByteBuffer incomingBuffer = ByteBuffer.allocateDirect(2);
        ByteBuffer outgoingBuffer = ByteBuffer.wrap("World".getBytes());
        Charset charset = Charset.defaultCharset();
        CharsetDecoder decoder = charset.newDecoder();
        String requestMsg = "";
        
        try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open())
        {
            if (serverSocketChannel.isOpen())
            {
                serverSocketChannel.configureBlocking(true);
                
                //set options
                serverSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024);
                serverSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
                
                //bind the server socket channel to local address
                serverSocketChannel.bind(new InetSocketAddress(SERVER_IP, SERVER_PORT));
                while (true)
                {
                    try (SocketChannel socketChannel = serverSocketChannel.accept())
                    {
                        
                        while (socketChannel.read(incomingBuffer) != -1)
                        {
                            incomingBuffer.flip();
                            String msgReceived = decoder.decode(incomingBuffer).toString();
                            System.out.println("Msg received in this loop : " + msgReceived);
                            requestMsg = requestMsg + msgReceived;
                            if (incomingBuffer.hasRemaining())
                            {
                                incomingBuffer.compact();
                            }
                            else
                            {
                                incomingBuffer.clear();
                            }
                        }
                        System.out.println("Request from " + socketChannel.getRemoteAddress() 
                                                           + " : " + requestMsg);
                        socketChannel.write(outgoingBuffer);
                        outgoingBuffer.flip();
                    }
                    catch (IOException ex)
                    {
                        ex.printStackTrace();
                    }
                }
            }
            else
            {
                System.out.println("The server socket channel cannot be opened!");
            }
        }
        catch (IOException ex)
        {
            System.err.println(ex);
        }
    }
}
Blocking TCP Client
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

public class BlockingTcpClient
{
    public static void main(String[] args)
        throws IOException
    {
        final int SERVER_PORT = 9001;
        final String SERVER_IP = "127.0.0.1";
        ByteBuffer receivingBuffer = ByteBuffer.allocateDirect(2);
        ByteBuffer sendingBuffer = ByteBuffer.wrap("Hello".getBytes());
        Charset charset = Charset.defaultCharset();
        CharsetDecoder decoder = charset.newDecoder();
        String responseMsg = "";
        //create a new socket channel
        try (SocketChannel socketChannel = SocketChannel.open())
        {
            if (socketChannel.isOpen())
            {
                //set the blocking mode
                socketChannel.configureBlocking(true);
                
                socketChannel.setOption(StandardSocketOptions.SO_SNDBUF, 1024);
                socketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024);
                socketChannel.setOption(StandardSocketOptions.SO_LINGER, 10);
            
                //establish channel connection
                socketChannel.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT));
                if (socketChannel.isConnected())
                {
                    //sending data
                    socketChannel.write(sendingBuffer);
                    socketChannel.shutdownOutput();
                    //receving data
                    while (socketChannel.read(receivingBuffer) != -1)
                    {
                        receivingBuffer.flip();
                        String msgReceived = decoder.decode(receivingBuffer).toString();
                        System.out.println("Msg received in this loop : " + msgReceived);
                        responseMsg = responseMsg + msgReceived; 
                        if (receivingBuffer.hasRemaining())
                        {
                            receivingBuffer.compact();
                        }
                        else
                        {
                            receivingBuffer.clear();
                        }
                    }
                   
                    System.out.println("Response from server : "+ responseMsg);
                }
                else
                {
                    System.out.println("The connection cannot be established!");
                }
            }
            else
            {
                System.out.println("The socket channel cannot be opened!");
            }
        }
        catch (IOException ex)
        {
            System.err.println(ex);
        }


    }
}
 

Wednesday, January 11, 2012

Java 7 new features - 4. NIO2 : B. Watch Service


<< Previous Table of Categories Next >>


In some high volume traffic system (e.g. telecommunication environment), some resource files (for example configuration files) needed to be cached in the memory. When the files are changed, the system needs to be aware and reload them into the memory. Another case is that when we need to reduce the system down time as little as possible, we also need to have a system which can support hot deployment and dynamic reloading because customers may not be able to afford to do stop and restart frequently. In both cases, we need to have a mechanism to detect whether the original resource has been changed or not. In previous Java version(<7), one of methods we used is checking the last modified timestamps of those files. The following code snippet can be seen everywhere:
 
 ...
 private long lastModifiedTime = 0;
 ...
 long fileModified = file.lastModified();
 if (fileModified > lastModifiedTime)
 {
   //reload the resource files 
   reload();
   lastModifiedTime = fileModified;
 }
 ...
From Java 7, we can easily use the Watch Service API which uses the underlying file system functionalities to watch the file system for changes (Create, Modify, Overflow, Delete). To meet the requirement mentioned above, we can write some code like below:
 
 ...
 private final static String DITECTORY_TO_WATCH = "some_directory";
 private final static String FILE_TO_WATCH = "some_file";
 ...
 FileSystem fs = FileSystems.getDefault();
 WatchService ws = fs.newWatchService();
 Path path = fs.getPath(DITECTORY_TO_WATCH);
 path.register(ws, StandardWatchEventKinds.ENTRY_MODIFY);
 while(true)
 {
   WatchKey key = ws.take();
   List<Watchevent<?>> events = key.pollEvents();
   for (WatchEvent event: events)
   {
     if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY)
     {
      if(event.context().toString().equals(FILE_TO_WATCH))
      {
  //reload the resource files 
  reload();
      }
     }
   }
   key.reset();
 }
 ...
This will be much more efficient than the previous solution. Howerver, you need to pay attention of the following points:
  1. please don't forget put the following line (which can be ignored by some developer) in your infinite loop:
    key.reset()
    Without this, the system is not able to detect the future change.
  2. Inside the "WatchService", "ReentrantLock" is used (inside the LinkedBlockingDeque class).
    So the Watch Service needs to be in a separate Thread from your other paralleling running tasks.
  3. Instead of using ws.take(), you can also use ws.poll. Their differencs are described below:
    • pull(): Retrieves and removes the next watch key, or if no key is availabe, a null will be returned immediately.
    • poll(long timeout, TimeUnit unit): Retrieves and removes the next watch key, waiting up to the specified wait time if still no key available, then it will return null.
    • take(): Retrieves and removes next watch key, keeps waiting until there is a key available.

Monday, January 9, 2012

Java 7 new features - 3. NIO2 : A. Copy files with Path API


<< Previous Table of Categories Next >>


Java 7 has a new generation of NIO which is NIO2. There are some significant enhancements in NIO2. One of them is the Path API.
 
    /**
      * Feel free to copy and use this method
      * If you have any comments or better solutions, please paste on my blog: 
      * http://blog.yanmingyu.com or email me feedback.andrewyu@gmail.com 
      * 
      * When we copy files, there are several options for us now. I think copying with NIO2 
      * is the easiest one now.(Even though "copyFileWithOSCommand" is the fast one, but it may
      * not be allowed to use sometimes).
      */   
Copy files by using Windows/Liunx/Unix system command
 
    public static void copyFileWithOSCommand(String sourceFilename, String targetFilename)
        throws IOException
    {
        String cmd = "cmd /C copy ";
        String os = System.getProperty("os.name");
        os = os.toLowerCase();
        if(os.indexOf("windows")>=0)
        {
            os = "cp ";
        }
        cmd = cmd + sourceFilename + " " + targetFilename;
        Runtime.getRuntime().exec(cmd);
    }
Copy files by using traditional Stream
 
    public static void copyFileWithStream(String sourceFilename, String targetFilename)
        throws IOException
    {
        InputStream in = null;
        OutputStream out = null;
        try
        {
            in = new FileInputStream(sourceFilename);
            out = new FileOutputStream(targetFilename);
            byte[] buf = new byte[4098];
            int len;
            while ((len = in.read(buf)) > 0)
            {
                out.write(buf, 0, len);
            }
        }
        finally
        {
            if (in != null)
            {
                in.close();
            }
            if (out != null)
            {
                out.close();
            }
        }
    }
Copy files by using the first generation NIO transfer
 
    public static void copyFileWithNIO(String sourceFilename, String targetFilename)
        throws IOException
    {
        FileChannel source = null;
        FileChannel target = null;
        try
        {
            source = new FileInputStream(sourceFilename).getChannel();
            target = new FileOutputStream(targetFilename).getChannel();
            target.transferFrom(source, 0, source.size());
        }
        finally
        {
            if (source != null)
            {
                source.close();
            }
            if (target != null)
            {
                target.close();
            }
        }
    }
Copy files by using NIO2 which is provided by Java 7
 
    public static void copyFileWithNIO2(String sourceFilename, String targetFilename)
        throws IOException
    {
        Path source = Paths.get(sourceFilename);
        Path target = Paths.get(targetFilename);
        Path copy = Files.copy(source, target);
    }

Sunday, January 8, 2012

Java 7 new features - 2. Automatic Resource Management


<< Previous Table of Categories Next >>


With this feature, resources such as Connections, Files, Input/OutStreams, etc. will be closed automatically in the "try" block rather than done manually by the developer. I personally think this is one of the most important features. Prior to Java 7, developers have to remember to close resource when programming in JDBC, Socket, File IO and etc. They need to do something like:
 
 try 
 {
  ...
 } 
 catch (SQLException e) 
 {
   // handle exception
 } 
 finally 
 {
  ...
  if (conn != null) 
  {
    try 
    {
      conn.close();
    } 
    catch (SQLException e)  
    {
    }
    conn = null;
  }
  ...
 }
This is not only annoying, but also error-prone. Especially for JDBC, if there are too many pending connections, the database will stop working in the end. In Java 7, you can use and test the automatic resource management like following:
 
 ...
 Connection conn = null;
 try(Connection connection=DriverManager.getConnection(url, "username", "password"))
 {
  conn=connection;
  ...
 }
 //the following code is just for testing
 try
 {
   System.out.println("connection isClosed? "+conn.isClosed());
 }
 catch(Exception e){}
Unfortunately however not all Java IDEs have a good support for this feature, some of them will complain "not a valid expression statement". So when you want to use this feature, please make sure that you have the latest IDE.

Java 7 new features - 1. Switch on Strings


<< Previous Table of Categories Next >>


 
   /**
      * If you have any comments or better examples, please paste on my blog:
      * http://blog.yanmingyu.com or email me feedback.andrewyu@gmail.com
      * 
      * From Java 7, developers can use "switch" statement on String.
      * Please refer to the following example about how to use it.
      */
  public static String getAustralianCapitalCity(String stateOrTerritory)
  {
    String capitalCity = "unknown";
    switch (stateOrTerritory)
    {
      case "NSW":
      case "New South Wales":
        capitalCity = "Sydney";
        break;
      case "QLD":
      case "Queensland":
        capitalCity = "Brisbane";
        break;
      case "VIC":
      case "Victoria":
        capitalCity = "Melbourne";
        break;
      case "SA":
      case "South Australia":
        capitalCity = "Adelaide";
        break;
      case "TAS":
      case "Tasmania":
        capitalCity = "Hobart";
        break;
      case "NT":
      case "Northern Territory":
        capitalCity = "Darwin";
        break;
      case "ACT":
      case "Australian Capital Territory":
        capitalCity = "Canberra";
        break;
      default:
        break;
    }
    return capitalCity;
  }