You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by sc...@apache.org on 2008/03/06 18:19:11 UTC

svn commit: r634354 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/attachments/impl/ axiom-tests/src/test/java/org/apache/axiom/attachments/impl/

Author: scheu
Date: Thu Mar  6 09:19:09 2008
New Revision: 634354

URL: http://svn.apache.org/viewvc?rev=634354&view=rev
Log:
WSCOMMONS-307
Contributor:Rich Scheuerle
Created a bigger buffer in BufferUtils.
Added code to use FileChannel within BufferUtils if the output stream is a FileOutputStream.
Added a unit test for BufferUtils.

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/
    webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java?rev=634354&r1=634353&r2=634354&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/attachments/impl/BufferUtils.java Thu Mar  6 09:19:09 2008
@@ -18,9 +18,13 @@
  */
 package org.apache.axiom.attachments.impl;
 
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
 
 /**
  * Attachment processing uses a lot of buffers.
@@ -29,7 +33,8 @@
  */
 public class BufferUtils {
     
-    public static final int BUFFER_LEN = 4 * 1024;
+    static int BUFFER_LEN = 100 * 1024;         // Copy Buffer size
+    static boolean ENABLE_FILE_CHANNEL = true;  // Enable file channel optimization 
     
     /**
      * Private utility to write the InputStream contents to the OutputStream.
@@ -42,9 +47,16 @@
         throws IOException {
             
         
+        // If this is a FileOutputStream, use th
+        if (ENABLE_FILE_CHANNEL && os instanceof FileOutputStream) {
+            if (inputStream2FileOutputStream(is, (FileOutputStream) os)) {
+                return;
+            }
+        }
         byte[] buffer = new byte[BUFFER_LEN];
         int bytesRead = is.read(buffer);
         
+        
         // Continue reading until no bytes are read and no
         // bytes are now available.
         while (bytesRead > 0 || is.available() > 0) {
@@ -85,5 +97,68 @@
         return totalWritten;
     }
     
-  
+    /**
+     * Opimized writing to FileOutputStream using a channel
+     * @param is
+     * @param fos
+     * @return false if lock was not aquired
+     * @throws IOException
+     */
+    public static boolean inputStream2FileOutputStream(InputStream is, 
+                                                FileOutputStream fos)
+        throws IOException {
+        
+        // See if a file channel and lock can be obtained on the FileOutputStream
+        FileChannel channel = null;
+        FileLock lock = null;
+        ByteBuffer bb = null;
+        try {
+            channel = fos.getChannel();
+            if (channel != null) {
+                lock = channel.tryLock();
+            }
+            bb = ByteBuffer.allocate(BUFFER_LEN);
+        } catch (Throwable t) {
+        }
+        if (lock == null || bb == null || !bb.hasArray()) {
+            return false;  // lock could not be set or bb does not have direct array access
+        }
+        
+        try {
+
+            // Read directly into the ByteBuffer array
+            int bytesRead = is.read(bb.array());
+            // Continue reading until no bytes are read and no
+            // bytes are now available.
+            while (bytesRead > 0 || is.available() > 0) {
+                if (bytesRead > 0) {
+                    int written = 0;
+                    
+                    
+                    if (bytesRead < BUFFER_LEN) {
+                        // If the ByteBuffer is not full, allocate a new one
+                        ByteBuffer temp = ByteBuffer.allocate(bytesRead);
+                        temp.put(bb.array(), 0, bytesRead);
+                        temp.position(0);
+                        written = channel.write(temp);
+                    } else {
+                        // Write to channel
+                        bb.position(0);
+                        written = channel.write(bb);
+                        bb.clear();
+                    }
+                  
+                }
+                
+                // REVIEW: Do we need to ensure that bytesWritten is 
+                // the same as the number of bytes sent ?
+                
+                bytesRead = is.read(bb.array());
+            }
+        } finally {
+            // Release the lock
+           lock.release();
+        }
+        return true;
+    }
 }

Added: webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java?rev=634354&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/attachments/impl/BufferUtilsTests.java Thu Mar  6 09:19:09 2008
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.attachments.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import junit.framework.TestCase;
+
+/**
+ * Simple test for the BufferUtils copying code
+ */
+public class BufferUtilsTests extends TestCase {
+
+    byte[] bytes;
+    static final int MAX = 1024 * 1024;
+   
+    protected void setUp() throws Exception {
+        bytes = new byte[MAX];
+        for (int i = 0; i < MAX /20; i++) {
+            for (int j = 0; j < 20; j++) {
+                bytes[i*20 + j] = (byte) j;
+            }
+        }
+    }
+
+    /**
+     * Create a temp file, and write to it using buffer utils
+     * @throws Exception
+     */
+    public void test() throws Exception {
+        // Create temp file
+        File file =  File.createTempFile("bufferUtils", "tst");
+        try {
+            //System.out.println(file.getCanonicalPath());
+            //System.out.println(file.getName());
+            FileOutputStream fos = new FileOutputStream(file, true);
+            for (int i = 0; i < 20; i++) {
+                //long start = System.currentTimeMillis();
+                ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                BufferUtils.inputStream2OutputStream(bais, fos);
+                fos.flush();
+                //long end = System.currentTimeMillis();
+                //System.out.println(end - start);
+
+            }
+            fos.close();
+            FileInputStream fis = new FileInputStream(file);
+            byte[] buffer = new byte[20];
+            fis.read(buffer);
+            for (int i = 0; i < buffer.length; i++) {
+                //System.out.println(buffer[i]);
+                assertTrue(buffer[i] == (byte) i);
+            }
+        } finally {
+            file.delete();
+        }        
+        file.delete();
+    }
+    
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: commons-dev-help@ws.apache.org