alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Transfers.java)

This example Java source code file (Transfers.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

bytebuffer, failure, filechannel, intgenerator, ioexception, max_file_size, nio, random, randomaccessfile, readablebytechannel, source, string, target, util, writablebytechannel, wrong

The Transfers.java Java example source code

/*
 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/* @test
 * @summary Comprehensive test for FileChannel.transfer{From,To}
 * @bug 4708120
 * @author Mark Reinhold
 */

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;


public class Transfers {

    static PrintStream out = System.out;

    private static class Failure
        extends RuntimeException
    {

        Failure(Exception x) {
            super(x);
        }

        Failure(String s) {
            super(s);
        }

    }


    // -- Writing and reading random bytes --

    private static void writeBytes(byte[] ba, FileChannel fc,
                                   int off, int len)
        throws IOException
    {
        fc.position(off);
        if (fc.write(ByteBuffer.wrap(ba, 0, len)) != len)
            throw new IOException("Incomplete write");
        fc.position(0);
    }

    private static void writeRandomBytes(long seed,
                                         FileChannel fc, int off, int len)
        throws IOException
    {
        Random r = new Random(seed);
        byte[] ba = new byte[len];
        r.nextBytes(ba);
        writeBytes(ba, fc, off, len);
    }

    private static void writeZeroBytes(FileChannel fc, int off, int len)
        throws IOException
    {
        byte[] ba = new byte[len];
        writeBytes(ba, fc, off, len);
    }

    private static void checkBytes(FileChannel fc, int off, int len,
                                   byte[] bytes)
        throws IOException
    {
        ByteBuffer bb = ByteBuffer.allocate(len);
        fc.position(off);
        if (fc.read(bb) != len)
            throw new IOException("Incomplete read");
        bb.flip();
        ByteBuffer bab = ByteBuffer.wrap(bytes, 0, len);
        if (!bb.equals(bab))
            throw new Failure("Wrong data written");
    }

    private static void checkRandomBytes(FileChannel fc, int off, int len,
                                         long seed)
        throws IOException
    {
        byte[] ba = new byte[len];
        Random r = new Random(seed);
        r.nextBytes(ba);
        checkBytes(fc, off, len, ba);
    }

    private static void checkZeroBytes(FileChannel fc, int off, int len)
        throws IOException
    {
        byte[] ba = new byte[len];
        checkBytes(fc, off, len, ba);
    }

    // For debugging
    //
    private static void dump(FileChannel fc)
        throws IOException
    {
        int sz = (int)fc.size();
        ByteBuffer bb = ByteBuffer.allocate(sz);
        fc.position(0);
        if (fc.read(bb) != sz)
            throw new IOException("Incomplete read");
        bb.flip();
        byte prev = -1;
        int r = 0;                      // Repeats
        int n = 0;
        while (bb.hasRemaining() && (n < 32)) {
            byte b = bb.get();
            if (b == prev) {
                r++;
                continue;
            }
            if (r > 0) {
                int c = prev & 0xff;
                if (c < 0x10)
                    out.print('0');
                out.print(Integer.toHexString(c));
                if (r > 1) {
                    out.print("[");
                    out.print(r);
                    out.print("]");
                }
                n++;
            }
            prev = b;
            r = 1;
        }
        if (r > 0) {
            int c = prev & 0xff;
            if (c < 0x10)
                out.print('0');
            out.print(Integer.toHexString(c));
            if (r > 1) {
                out.print("[");
                out.print(r);
                out.print("]");
            }
            n++;
        }
        if (bb.hasRemaining())
            out.print("...");
        out.println();
    }



    static File sourceFile;
    static File targetFile;

    // -- Self-verifying sources and targets --

    static abstract class Source {

        protected final int size;
        protected final long seed;
        private final String name;

        Source(int size, long seed, String name) {
            this.size = size;
            this.seed = seed;
            this.name = name;
        }

        String name() {
            return name;
        }

        abstract ReadableByteChannel channel();

        abstract void verify() throws IOException;

    }

    static class FileSource
        extends Source
    {
        private final File fn;
        private final RandomAccessFile raf;
        private final FileChannel fc;

        FileSource(int size, long seed) throws IOException {
            super(size, seed, "FileChannel");
            fn = sourceFile;
            raf = new RandomAccessFile(fn, "rw");
            fc = raf.getChannel();
            fc.position(0);
            writeRandomBytes(seed, fc, 0, size);
        }

        ReadableByteChannel channel() {
            return fc;
        }

        void verify() throws IOException {
            if (fc.position() != size)
                throw new Failure("Wrong position: "
                                  + fc.position() + " (expected " + size +
                                  ")");
            checkRandomBytes(fc, 0, size, seed);
            fc.close();
            raf.close();                // Bug in 1.4.0
        }

    }

    static class UserSource
        extends Source
    {
        private ReadableByteChannel ch;
        private final ByteBuffer src;

        UserSource(int size, long seed) {
            super(size, seed, "UserChannel");

            final byte[] bytes = new byte[size + 1];
            Random r = new Random(seed);
            r.nextBytes(bytes);
            src = ByteBuffer.wrap(bytes);

            ch = new ReadableByteChannel() {
                    public int read(ByteBuffer dst) {
                        if (!src.hasRemaining())
                            return -1;
                        int nr = Math.min(src.remaining(), dst.remaining());
                        ByteBuffer s = src.duplicate();
                        s.limit(s.position() + nr);
                        dst.put(s);
                        src.position(src.position() + nr);
                        return nr;
                    }
                    public boolean isOpen() {
                        return true;
                    }
                    public void close() { }
                };
        }

        ReadableByteChannel channel() {
            return ch;
        }

        void verify() {
            if (src.remaining() != 1)
                throw new Failure("Source has " + src.remaining()
                                  + " bytes remaining (expected 1)");
        }

    }

    static abstract class Target {

        protected final int size;
        protected final long seed;
        private final String name;

        Target(int size, long seed, String name) {
            this.size = size;
            this.seed = seed;
            this.name = name;
        }

        String name() {
            return name;
        }

        abstract WritableByteChannel channel();

        abstract void verify() throws IOException;

    }

    static class FileTarget
        extends Target
    {
        private final File fn;
        private final RandomAccessFile raf;
        private final FileChannel fc;

        FileTarget(int size, long seed) throws IOException {
            super(size, seed, "FileChannel");
            fn = targetFile;
            raf = new RandomAccessFile(fn, "rw");
            fc = raf.getChannel();
            fc.position(0);
        }

        WritableByteChannel channel() {
            return fc;
        }

        void verify() throws IOException {
            if (fc.position() != size)
                throw new Failure("Wrong position: "
                                  + fc.position() + " (expected " + size + ")");
            checkRandomBytes(fc, 0, size, seed);
            fc.close();
            raf.close();                // Bug in 1.4.0
        }

    }

    static class UserTarget
        extends Target
    {
        private WritableByteChannel ch;
        private final ByteBuffer dst;

        UserTarget(int size, long seed) {
            super(size, seed, "UserChannel");
            dst = ByteBuffer.wrap(new byte[size + 1]);

            ch = new WritableByteChannel() {
                    public int write(ByteBuffer src) {
                        int nr = Math.min(src.remaining(), dst.remaining());
                        ByteBuffer s = src.duplicate();
                        s.limit(s.position() + nr);
                        dst.put(s);
                        src.position(src.position() + nr);
                        return nr;
                    }
                    public boolean isOpen() {
                        return true;
                    }
                    public void close() { }
                };
        }

        WritableByteChannel channel() {
            return ch;
        }

        void verify() {
            if (dst.remaining() != 1)
                throw new Failure("Destination has " + dst.remaining()
                                  + " bytes remaining (expected 1)");
            byte[] ba = new byte[size];
            Random r = new Random(seed);
            r.nextBytes(ba);
            dst.flip();
            ByteBuffer rbb = ByteBuffer.wrap(ba, 0, size);
            if (!dst.equals(rbb))
                throw new Failure("Wrong data written");
        }

    }


    // Generates a sequence of ints of the form 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
    // 15, 16, 17, 31, 32, 33, ..., 2^i-1, 2^i, 2^i+1, ..., max.

    static class IntGenerator {

        private int max;
        private int cur = -1;
        private int p2 = 8;

        IntGenerator(int max) {
            this.max = max;
        }

        boolean hasNext() {
            return cur < max;
        }

        int next() {
            if (cur >= max)
                throw new IllegalStateException();
            if (cur < 6) {
                cur++;
                return cur;
            }
            if (cur == p2 + 1) {
                p2 <<= 1;
                cur = p2 - 1;
                return cur;
            }
            cur++;
            return cur;
        }

    }


    // -- Tests --

    private static final int MAX_XFER_SIZE = 1 << 14;
    private static final int MAX_FILE_SIZE = MAX_XFER_SIZE << 1;

    private static boolean debug = false;
    private static boolean verbose = false;

    static void show(String dir, String channelName, int off, int len) {
        if (!verbose)
            return;
        out.println(dir + " " + channelName +
                    ": offset " + off + ", length " + len);
    }

    static void testTo(long seed, FileChannel fc, int off, int len, Target tgt)
        throws IOException
    {
        show("To", tgt.name(), off, len);

        // Clear source, then randomize just the source region
        writeZeroBytes(fc, 0, MAX_FILE_SIZE);
        writeRandomBytes(seed, fc, off, len);

        // Randomize position
        int pos = (int)seed & 0xfff;
        fc.position(pos);

        int n = (int)fc.transferTo(off, len, tgt.channel());
        if (n != len)
            throw new Failure("Incorrect transfer length: " + n
                              + " (expected " + len + ")");

        // Check that source wasn't changed
        if (fc.position() != pos)
            throw new Failure("Position changed");
        if (debug)
            dump(fc);
        checkRandomBytes(fc, off, len, seed);
        writeZeroBytes(fc, off, len);
        checkZeroBytes(fc, 0, MAX_FILE_SIZE);

        // Check that target was updated correctly
        tgt.verify();
    }

    static void testFrom(long seed, Source src, FileChannel fc, int off, int len)
        throws IOException
    {
        show("From", src.name(), off, len);

        // Clear target
        writeZeroBytes(fc, 0, MAX_FILE_SIZE);

        // Randomize position
        int pos = (int)seed & 0xfff;
        fc.position(pos);

        int n = (int)fc.transferFrom(src.channel(), off, len);
        if (n != len)
            throw new Failure("Incorrect transfer length: " + n
                              + " (expected " + len + ")");

        // Check that source didn't change, and was read correctly
        src.verify();

        // Check that target was updated correctly
        if (fc.position() != pos)
            throw new Failure("Position changed");
        if (debug)
            dump(fc);
        checkRandomBytes(fc, off, len, seed);
        writeZeroBytes(fc, off, len);
        checkZeroBytes(fc, 0, MAX_FILE_SIZE);
    }

    public static void main(String[] args)
        throws Exception
    {
        if (args.length > 0) {
            if (args[0].indexOf('v') >= 0)
                verbose = true;
            if (args[0].indexOf('d') >= 0)
                debug = verbose = true;
        }

        sourceFile = File.createTempFile("xfer.src.", "");
        sourceFile.deleteOnExit();
        targetFile = File.createTempFile("xfer.tgt.", "");
        targetFile.deleteOnExit();

        File fn = File.createTempFile("xfer.fch.", "");
        fn.deleteOnExit();
        FileChannel fc = new RandomAccessFile(fn, "rw").getChannel();

        Random rnd = new Random();
        int failures = 0;

        for (boolean to = false;; to = true) {
            for (boolean user = false;; user = true) {
                if (!verbose)
                    out.print((to ? "To " : "From ") +
                              (user ? "user channel" : "file channel")
                              + ":");
                IntGenerator offGen = new IntGenerator(MAX_XFER_SIZE + 2);
                while (offGen.hasNext()) {
                    int off = offGen.next();
                    if (!verbose) out.print(" " + off);
                    IntGenerator lenGen = new IntGenerator(MAX_XFER_SIZE + 2);
                    while (lenGen.hasNext()) {
                        int len = lenGen.next();
                        long s = rnd.nextLong();
                        String chName = null;
                        try {
                            if (to) {
                                Target tgt;
                                if (user)
                                    tgt = new UserTarget(len, s);
                                else
                                    tgt = new FileTarget(len, s);
                                chName = tgt.name();
                                testTo(s, fc, off, len, tgt);
                            }
                            else {
                                Source src;
                                if (user)
                                    src = new UserSource(len, s);
                                else
                                    src = new FileSource(len, s);
                                chName = src.name();
                                testFrom(s, src, fc, off, len);
                            }
                        } catch (Failure x) {
                            out.println();
                            out.println("FAILURE: " + chName
                                        + ", offset " + off
                                        + ", length " + len);
                            x.printStackTrace(out);
                            failures++;
                        }
                    }
                }
                if (!verbose)
                    out.println();
                if (user)
                    break;
            }
            if (to)
                break;
        }

        sourceFile.delete();
        targetFile.delete();
        fn.delete();

        if (failures > 0) {
            out.println();
            throw new RuntimeException("Some tests failed");
        }

    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java Transfers.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.