Java中各种IOStream以及NIO Chanel的性能比较

      当前流行的JDK版本还是1.5和1.6,拿JDK1.6为例,共有202个包,3777个类(当然加上非Java的这三个类 javax.servlet,javax.servlet.http,javax.servlet.jsp)就是205个包,3817个类以及32043 个方法。但其中大部分的类和方法都是在IO包和图形界面包中,其中SWING和AWT更是占了近1/3的类和方法数,可见Java语言对IO和GUI的重 视程度(尽管GUI的图形界面和性能辜负了SUN和众多的Javaer)。

     回到主题,在IO包中有着众多甚至繁杂的类和方法,来两个 图先:

字节流部分的类层次结构:



 字符流部分的类层次结构:



      那么既然IO里有这么多个操作流,究竟哪一个的性能是最优的呢?其实答案大家都知道,没有最优,只能通过经验和实际情况来选择最适合的流以完成我们的需求。

      其实在IO包里,真正能够称得上“流”的却只有字节流的InputStream和OutputStream以及字符流的Reader和Writer。除此4个基本流以外,其余的类在严格意义上说都不是流 只是在4个基本流的基础上,根据各自的特性进行了特定的封装。接下来本文就拿拷贝文件为例,通过GUI来直观的体现一下几个常有流的性能,因为源文件不是文本文件,所以选择的4个流分别是FileInputStream,BufferedInputStream(系统缓存类),自定义缓冲类以及在JDK1.4中才出现的FileChanel。

1.首先看FileInputStream的例子:

		InputStream fis = null;
		OutputStream fos = null;
		try {
			fis = new FileInputStream(strFileFrom);
			fos = new FileOutputStream(strFileTo, true);
			while (true) {
				int iEOF = fis.read();
				if (iEOF == -1) {
					break;
				}
				fos.write(iEOF);
			}
		} finally {
			if (fis != null) {
				fis.close();
			}
			if (fos != null) {
				fos.close();
			}
		}

FileInputStream类的特点: 从JRE源代码来看该类从文件系统中的某个文件中获得输入字节 ,哪些文件可以取决于定义的主机环境,该类也可以用于读取图像数据之类的原始字节流。也就是说此类还是以每次读取一个字节的形式进行的数据读取,在性能上并没有什么提升。

2.再看BufferedInputStream(系统缓冲类)

		InputStream bis = null;
		OutputStream bos = null;
		try {
			InputStream in = new FileInputStream(strFileFrom);
			bis = new BufferedInputStream(in);
			OutputStream out = new FileOutputStream(strFileTo);
			bos = new BufferedOutputStream(out);
			int iEOF = -1;
			while ((iEOF = bis.read()) != -1) {
				bos.write(iEOF);
			}
		} finally {
			if (bis != null) {
				bis.close();
			}
			if (bos != null) {
				bos.close();
			}
		}

       虽然从以上代码来看,和例子1的实现并没有什么区别,不过这个系统缓冲类在FileInputStream类的基础上进行了Buffered的封装。如下图,buffer size为8192个字节。

    /**
     * Creates a new buffered output stream to write data to the
     * specified underlying output stream.
     *
     * @param   out   the underlying output stream.
     */
    public BufferedOutputStream(OutputStream out) {
	this(out, 8192);
    } 

Java 语言中一般的输出流和输入流(例子1)都是采用的单字节的读取办法,进行数据的IO操作,也就是说每次只能读取一个字节的数据,这种方法显然烦琐而且效率比较低下。 当程序需要读取或者写入一个比较大的文件的时候,比如10M甚至更大,如果每次都是读取或者写入一个字节,那么完成这个操作的次数就会增加了,比如10M 那么就需要10MB次这样的操作了。所以Java语言本身在IO读写的时候已经提供了系统缓冲类来进行此部分的操作,众所周知使用缓冲区进行读写操作的时 候会使得性能有大大的提高。

3.自定义缓冲类:

虽然Java为我们提供了一个缓冲类,但在读取一些文件的时候就未必显得合理从而其性能优势就没法体现,所以根据实际情况写一个自定义的缓冲类来对文件进行读写操作,会进一步的提升性能。将我们的程序的执行时间进一步缩短以给用户良好的相应效果。

		InputStream in = null;
		OutputStream out = null;
		try {
			in = new FileInputStream(strFileFrom);
			out = new FileOutputStream(strFileTo);
			int availableLength = in.available();
			byte[] totalBytes = new byte[availableLength];
			int bytedata = in.read(totalBytes);
			out.write(totalBytes);
		} finally {
			if (in != null) {
				in.close();
			}
			if (out != null) {
				out.close();
			}
		}

 从代码中可以看出,这个自定义的缓冲方法将缓冲size设置成了一个可变的大小来提升性能,当然若已知的文件大小是相对固定的,也可以将缓冲区size设置成固定的长度。例如: byte [] buffer =  new byte [4096 ];

PS:因为本地的JDK环境是1.6的 所以对文件流还是进行了显式关闭的操作。

4.NIO包中的FileChanel

		FileInputStream fin = new FileInputStream(strFileFrom);
		FileOutputStream fout = new FileOutputStream(strFileTo);
		FileChannel inChannel = fin.getChannel();
		FileChannel outChannel = fout.getChannel();
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		while (true) {
			int ret = inChannel.read(buffer);
			if (ret == -1) {
				break;
			}
			buffer.flip();
			outChannel.write(buffer);
			buffer.clear(); 
		}

 FileChanel的好处是:以下引自戒子的博文

【多个并发线程可安全地 使用文件通道,可随时调用关闭方法 ,正如Channel接口中所指定,对于涉及通道位置或者可以更改文件大小的操作,在任意给定时间只能进行一个这样的操作 ,如果尝试在第一操作仍在进行时发起第二个操作,则会导致在第一个操作完成之前阻塞 第二个操作。可以并发处理其他操作,特别是采用显示位置的操作,但是否并发处理则取决于系统,因此是未指定的。 确保此类的实例所提供的文件视图与同一程序中其他实例所提供的相同文件视图是一致的。但是,此类的实例所提供的视图不一定与其他并发运行的程序所看到的视图一致,这取决于底层操作系统所执行的缓冲策略和各种网络文件系统协议所引入的延迟。 不管其他程序是以何种语言编写的,而且也不管是运行在相同机器 还是不同机器 上都是如此。此种不一致的确切性质取决于系统 ,因此是未指定的。此类没有定义打开现有文件或创建新文件的方法,以后的版本中可能添加这些方法。在此版本中,可从现有的  FileInputStream、FileOutputStream 或 RandomAccessFile   对象获得文件通道,方法是调用该对象的 getChannel 方法,这会返回一个连接到相同底层文件的文件通道。 文件通道的状态与其 getChannel 返回该通道的对象密切相关 。显式或者通过读取或写入字节来更改通道的位置将更改发起对象的文件位置,反之亦然。通过文件通道更改此文件的长度将更改通过发起对象看到的长度,反之亦然。通过写入字节更改此文件的内容将更改发起对象所看到的内容,反之亦然。 此类在各种情况下指定要求“允许读取操作”“允许写入操作”“允许读取和写入操作” 的某个实例。通过  FileInputStream  实例的 getChannel 方法所获得的通道将允许进行读取操作。通过  FileOutputStream  实例的 getChannel 方法所获得的通道将允许进行写入操作。最后,如果使用模式  "r"  创建  RandomAccessFile  实例,则通过该实例的 getChannel 方法所获得的通道将允许进行读取操作,如果使用模式  "rw"  创建实例,则获得的通道将允许进行读取和写入操作。 如果从文件输出流中获得了允许进行写入操作的文件通道,并且该输出流是通过调用  FileOutputStream (File, boolean ) 构造方法且为第二个参数传入  true  来创建的,则该文件通道可能处于添加模式 。在此模式中,每次调用相关的写入操作都会首先将位置移到文件的末尾,然后再写入请求的数据。在单个原子操作中是否移动位置和写入数据是与系统相关的,因此是未指定的。 】

最近翻看了一下NIO包中的方法。发现大部分方法都没有Java语言实现IO操作,而是用的C语言。那在性能上就不言而喻了。

接下来试着拷贝一个5MB的文件,看看其性能如何?



 可以看出, 没有任何封装的FileInputStream的效率是很差的吧?

再对一个33MB的文件进行拷贝,试试后三种流的性能.



 可以看出系统的缓冲流与自定义的缓冲流的性能还是有些区别的,但后两者的差距不是很大,最后来个512MB的文件(当然因为这个文件比较大,所以自定义的缓冲流的size设置成了默认大小8192的100倍):



 能够看出,适当的调整缓冲区的size会给性能带来一些提升,而新IO包的FileChanel类的性能优势也会随着源文件不断变大而逐渐明显。当然不排除一些测试环境的问题,但大致的差距应该如图所示。大家可以自行做个比较,下面把源代码附上供大家参考:

package ui;

import java.awt.BorderLayout;
import java.awt.Checkbox;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
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 javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class StreamTest implements ActionListener {

	// define
	private JFrame jfMain;
	private Container ct;
	private JPanel jpSelect, jpOpration, jpProcessBars, jpResults, jpProcessFIS,
			jpProcessNIO, jpProcessBIS, jpProcessUDB;
	private JSplitPane jspMain;
	private JMenuBar jmbMain;
	private JMenu jmTheme, jmExit;
	private JMenuItem jmiWindows, jmiWindowsClassic, jmiNimbus, jmiCDEMotif,
			jmiMetal, jmiGTK, jmiExit;
	private JFileChooser jfcSelect, jfcDirectory;

	private JTextField jtfSourceFile, jtfTargetDirectory;
	private JButton jbSourceFile, jbTargetDirectory, jbCopyStart, jbShowAnswer;

	private JLabel jlToolTips;
	private Checkbox cbFIS, cbNIO, cbBIS, cbUDB;

	private JProgressBar jpbFIS, jpbNIO, jpbBIS, jpbUDB;

	private final int nLeft = 10;
	private final int nTop = 10;
	private final int nHeight = 30;
	private final int nWidth = 500;

	private int nTime1Lasts;
	private int nTime2Lasts;
	private int nTime3Lasts;
	private int nTime4Lasts;
	private int nMaxTimeLasts;

	private JTextField jtfFIS, jtfNIO, jtfBIS, jtfUDB;

	private static StreamTest rw;
	private String strFileName;
	private String strSuffix;

	private static final String CDEMOTIF = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
	private static final String GTK = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
	private static final String METAL = "javax.swing.plaf.metal.MetalLookAndFeel";
	private static final String NIMBUS = "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel";
	private static final String WINDOWS = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
	private static final String WINDOWSCLASSIC = "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel";

	public StreamTest() {

		// initComponent
		initComponent();

		// initLayout
		initLayout();

		// addListener
		addListener();
	}

	private void initComponent() {
		jfMain = new JFrame("StreamPlus1.1_____by imp");
		ct = jfMain.getContentPane();

		jfcSelect = new JFileChooser();
		jfcSelect.setDialogTitle("choose a file which u want");
		jfcSelect.setFileSelectionMode(JFileChooser.FILES_ONLY);
		jfcDirectory = new JFileChooser();
		jfcDirectory
				.setDialogTitle("choose a directory where the file(s) copy to");
		jfcDirectory.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

		jmbMain = new JMenuBar();
		jmTheme = new JMenu("Theme");
		jmExit = new JMenu("Exit");
		jmiCDEMotif = new JMenuItem("CDEMotif");
		jmiGTK = new JMenuItem("GTK");
		jmiMetal = new JMenuItem("Metal");
		jmiNimbus = new JMenuItem("Nimbus");
		jmiWindows = new JMenuItem("Windows");
		jmiWindowsClassic = new JMenuItem("WindowsClassic");

		jmiExit = new JMenuItem("Exit");

		jspMain = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);
		jpSelect = new JPanel(null);

		jpOpration = new JPanel(new BorderLayout());
		jpProcessBars = new JPanel(new GridLayout(4, 1));
		jpResults = new JPanel(new GridLayout(4, 1));
		jpProcessFIS = new JPanel(new BorderLayout());
		jpProcessNIO = new JPanel(new BorderLayout());
		jpProcessBIS = new JPanel(new BorderLayout());
		jpProcessUDB = new JPanel(new BorderLayout());

		jtfSourceFile = new JTextField();
		jtfTargetDirectory = new JTextField();
		jbSourceFile = new JButton("Source File");
		jbSourceFile.setToolTipText("Choose Source File");
		jbTargetDirectory = new JButton("Target Directory");
		jbTargetDirectory.setToolTipText("Choose Target Directory");

		jlToolTips = new JLabel("Click Button[Copy] to copy files");
		jbCopyStart = new JButton("Copy");
		jbShowAnswer = new JButton("Show");

		cbFIS = new Checkbox("FileInputStream         ", false);
		cbNIO = new Checkbox("NIO[FileChannel]      ", true);
		cbBIS = new Checkbox("BufferedInputStream", true);
		cbUDB = new Checkbox("User-defined Buffer  ", true);

		jpbFIS = new JProgressBar();
		jpbNIO = new JProgressBar();
		jpbBIS = new JProgressBar();
		jpbUDB = new JProgressBar();

		jtfFIS = new JTextField();
		jtfNIO = new JTextField();
		jtfBIS = new JTextField();
		jtfUDB = new JTextField();

		jtfFIS.setColumns(5);
		jtfFIS.setHorizontalAlignment(JLabel.RIGHT);
		jtfNIO.setHorizontalAlignment(JLabel.RIGHT);
		jtfBIS.setHorizontalAlignment(JLabel.RIGHT);
		jtfUDB.setHorizontalAlignment(JLabel.RIGHT);

		jtfFIS.setEditable(false);
		jtfNIO.setEditable(false);
		jtfBIS.setEditable(false);
		jtfUDB.setEditable(false);

		strFileName = new String("");
		strSuffix = new String("");
	}

	private void initLayout() {

		// set Layout
		ct.setLayout(new BorderLayout());
		ct.add(jmbMain, BorderLayout.NORTH);
		ct.add(jspMain, BorderLayout.CENTER);

		// add jmbMain
		jmbMain.add(jmTheme);
		jmbMain.add(jmExit);

		jmTheme.add(jmiCDEMotif);
		jmTheme.add(jmiGTK);
		jmTheme.add(jmiMetal);
		jmTheme.add(jmiNimbus);
		jmTheme.add(jmiWindows);
		jmTheme.add(jmiWindowsClassic);
		jmExit.add(jmiExit);

		// jspMain
		jspMain.setTopComponent(jpSelect);
		jspMain.setBottomComponent(jpOpration);
		jspMain.setResizeWeight(0.7);
		jspMain.setDividerSize(3);

		// jpSelect.add()
		jpSelect.add(jtfSourceFile);
		jpSelect.add(jbSourceFile);
		jpSelect.add(jtfTargetDirectory);
		jpSelect.add(jbTargetDirectory);

		jpSelect.add(jlToolTips);
		jpSelect.add(jbCopyStart);
		jpSelect.add(jbShowAnswer);
		jbShowAnswer.setEnabled(false);

		// jpOpration.add()
		jpOpration.add(jpProcessBars, BorderLayout.CENTER);
		jpOpration.add(jpResults, BorderLayout.EAST);
		jpProcessBars.add(jpProcessFIS);
		jpProcessBars.add(jpProcessBIS);
		jpProcessBars.add(jpProcessUDB);
		jpProcessBars.add(jpProcessNIO);

		jpResults.add(jtfFIS);
		jpResults.add(jtfBIS);
		jpResults.add(jtfUDB);
		jpResults.add(jtfNIO);

		// jpProcess1.add()
		jpProcessFIS.add(cbFIS, BorderLayout.WEST);
		jpProcessFIS.add(jpbFIS, BorderLayout.CENTER);

		jpProcessNIO.add(cbNIO, BorderLayout.WEST);
		jpProcessNIO.add(jpbNIO, BorderLayout.CENTER);

		jpProcessBIS.add(cbBIS, BorderLayout.WEST);
		jpProcessBIS.add(jpbBIS, BorderLayout.CENTER);

		jpProcessUDB.add(cbUDB, BorderLayout.WEST);
		jpProcessUDB.add(jpbUDB, BorderLayout.CENTER);

		// setBounds
		jtfSourceFile.setBounds(nLeft, nTop, nWidth, nHeight);
		jbSourceFile.setBounds(nWidth + 2 * nLeft, nTop, 140, nHeight);

		jtfTargetDirectory
				.setBounds(nLeft, nHeight + 2 * nTop, nWidth, nHeight);

		jbTargetDirectory.setBounds(nWidth + 2 * nLeft, nHeight + 2 * nTop,
				140, nHeight);

		jlToolTips.setBounds(nLeft, 2 * nHeight + 3 * nTop, 350, nHeight);

		jbCopyStart.setBounds(new Rectangle(nWidth / 2 + 12 * nLeft, 2
				* nHeight + 3 * nTop, 140, nHeight));

		jbShowAnswer.setBounds(new Rectangle(nWidth + 2 * nLeft, 2 * nHeight
				+ 3 * nTop, 140, nHeight));

		// set size and visible
		jfMain.setSize(700, 380);
		jfMain.setResizable(false);
		jfMain.setVisible(true);
	}

	private void addListener() {
		jbCopyStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				// init
				jtfFIS.setText("");
				jtfNIO.setText("");
				jtfBIS.setText("");
				jtfUDB.setText("");
				nTime1Lasts = 0;
				nTime2Lasts = 0;
				nTime3Lasts = 0;
				nTime4Lasts = 0;

				File fileSource = new File(jtfSourceFile.getText());
				File fileTarget = new File(jtfTargetDirectory.getText());
				if (null != fileSource && fileSource.isFile()
						&& null != fileTarget && fileTarget.isDirectory()) {
					jlToolTips.setText("Copying Files...");
					int nIndex = jtfSourceFile.getText().lastIndexOf(".");
					int nIndexS = jtfSourceFile.getText().lastIndexOf("\\");
					strFileName = jtfSourceFile.getText().substring(
							nIndexS + 1, nIndex);
					System.out.println(strFileName);
					strSuffix = jtfSourceFile.getText().substring(nIndex);
					try {
						// setEnabled
						jbCopyStart.setEnabled(false);

						if (cbFIS.getState()) {
							// readByFileStream
							rw.readByFileInputStream(jtfSourceFile.getText(),
									jtfTargetDirectory.getText().concat(
											"/" + strFileName + "_FIS").concat(
											strSuffix));
						}

						if (cbBIS.getState()) {
							// readByBufferedInputStream
							rw.readByBufferedInputStream(jtfSourceFile
									.getText(), jtfTargetDirectory.getText()
									.concat("/" + strFileName + "_BIS").concat(
											strSuffix));
						}

						if (cbUDB.getState()) {
							// readByUserDefinedBuffer
							rw.readByUserDefinedBuffer(jtfSourceFile.getText(),
									jtfTargetDirectory.getText().concat(
											"/" + strFileName + "_UDB").concat(
											strSuffix));
						}

						if (cbNIO.getState()) {
							// readByNIO
							rw.readByNIO(jtfSourceFile.getText(),
									jtfTargetDirectory.getText().concat(
											"/" + strFileName + "_BR").concat(
											strSuffix));
						}
						// setEnabled
						jbCopyStart.setEnabled(true);
						jbShowAnswer.setEnabled(true);
					} catch (IOException e1) {
						e1.printStackTrace();
					}
					jlToolTips
							.setText("Copy Files Successed, Click Button[Show] To Show Results");
				}
			}
		});

		jbShowAnswer.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				jbShowAnswer.setEnabled(false);
				jtfFIS.setText(String.valueOf(nTime1Lasts).concat("ms"));
				jtfNIO.setText(String.valueOf(nTime2Lasts).concat("ms"));
				jtfBIS.setText(String.valueOf(nTime3Lasts).concat("ms"));
				jtfUDB.setText(String.valueOf(nTime4Lasts).concat("ms"));

				showAnswer();
				jbShowAnswer.setEnabled(true);
			}
		});

		jbSourceFile.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				jfcSelect.showOpenDialog(jfMain);
				File f = jfcSelect.getSelectedFile();
				if (null != f) {
					String strPath = f.getPath();
					jtfSourceFile.setText(strPath);
					int nIndex = strPath.lastIndexOf(".");
					strSuffix = strPath.substring(nIndex);
				}
			}
		});

		jbTargetDirectory.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				jfcDirectory.showOpenDialog(jfMain);
				File f = jfcDirectory.getSelectedFile();
				if (null != f) {
					String strPath = f.getPath();
					jtfTargetDirectory.setText(strPath);
				}
			}
		});

		jmiCDEMotif.addActionListener(this);
		jmiGTK.addActionListener(this);
		jmiMetal.addActionListener(this);
		jmiNimbus.addActionListener(this);
		jmiWindows.addActionListener(this);
		jmiWindowsClassic.addActionListener(this);

		jmiExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				jfMain.setVisible(false);
				jfMain.dispose();
				System.exit(0);
			}
		});
	}

	private void showAnswer() {
		jpbFIS.setMinimum(0);
		jpbNIO.setMinimum(0);
		jpbBIS.setMinimum(0);
		jpbUDB.setMinimum(0);
		nMaxTimeLasts = Math.max(Math.max(nTime1Lasts, nTime2Lasts), Math.max(
				nTime3Lasts, nTime4Lasts)) / 100;
		jpbFIS.setMaximum(nMaxTimeLasts);
		jpbNIO.setMaximum(nMaxTimeLasts);
		jpbBIS.setMaximum(nMaxTimeLasts);
		jpbUDB.setMaximum(nMaxTimeLasts);

		// show the percent
		jpbFIS.setStringPainted(true);
		jpbNIO.setStringPainted(true);
		jpbBIS.setStringPainted(true);
		jpbUDB.setStringPainted(true);

		Thread thread = new Thread(new Runnable() {
			public void run() {
				try {
					for (int i = 0; i <= nTime1Lasts / 100; i++) {
						jpbFIS.setValue(i);
						Thread.sleep(100);
					}

					for (int i = 0; i <= nTime3Lasts / 100; i++) {
						jpbBIS.setValue(i);
						Thread.sleep(100);
					}

					for (int i = 0; i <= nTime4Lasts / 100; i++) {
						jpbUDB.setValue(i);
						Thread.sleep(100);
					}
					
					for (int i = 0; i <= nTime2Lasts / 100; i++) {
						jpbNIO.setValue(i);
						Thread.sleep(100);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		thread.start();
	}

	/**
	 * Read file by FileInputStream 不使用缓冲区直接读写
	 * 
	 * @param strFileFrom
	 * @param strFileTo
	 * @throws IOException
	 */
	private void readByFileInputStream(String strFileFrom, String strFileTo)
			throws IOException {
		long lStartTime = System.currentTimeMillis();

		InputStream fis = null;
		OutputStream fos = null;
		try {
			fis = new FileInputStream(strFileFrom);
			fos = new FileOutputStream(strFileTo, true);
			while (true) {
				int iEOF = fis.read();
				if (iEOF == -1) {
					break;
				}
				fos.write(iEOF);
			}
		} finally {
			if (fis != null) {
				fis.close();
			}
			if (fos != null) {
				fos.close();
			}
		}

		long lEndTime = System.currentTimeMillis();
		System.out.println("readByFileStream() time: "
				+ (lEndTime - lStartTime) + "ms");
		nTime1Lasts = (int) (lEndTime - lStartTime);
	}

	/**
	 * Read file by readByNIO
	 * 
	 * @param strFileFrom
	 * @param strFileTo
	 * @throws IOException
	 */
	private void readByNIO(String strFileFrom, String strFileTo)
			throws IOException {
		long lStartTime = System.currentTimeMillis();
		FileInputStream fin = new FileInputStream(strFileFrom);
		FileOutputStream fout = new FileOutputStream(strFileTo);
		FileChannel inChannel = fin.getChannel();
		FileChannel outChannel = fout.getChannel();
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		while (true) {
			int ret = inChannel.read(buffer);
			if (ret == -1) {
				break;
			}
			buffer.flip(); // 该方法为父类Buffer的方法
			outChannel.write(buffer);
			buffer.clear(); // 该方法为父类Buffer的方法
		}

		long lEndTime = System.currentTimeMillis();
		System.out.println("readByNIO() time: "
				+ (lEndTime - lStartTime) + "ms");
		nTime2Lasts = (int) (lEndTime - lStartTime);
	}

	/**
	 * Read file by BufferedInputStream 使用系统自带缓冲类读写
	 * 
	 * @param strFileFrom
	 * @param strFileTo
	 * @throws IOException
	 */
	private void readByBufferedInputStream(String strFileFrom, String strFileTo)
			throws IOException {
		long lStartTime = System.currentTimeMillis();

		InputStream bis = null;
		OutputStream bos = null;
		try {
			InputStream in = new FileInputStream(strFileFrom);
			bis = new BufferedInputStream(in);
			OutputStream out = new FileOutputStream(strFileTo);
			bos = new BufferedOutputStream(out);
			int iEOF = -1;
			while ((iEOF = bis.read()) != -1) {
				bos.write(iEOF);
			}
		} finally {
			if (bis != null) {
				bis.close();
			}
			if (bos != null) {
				bos.close();
			}
		}

		long lEndTime = System.currentTimeMillis();
		System.out.println("readByBufferedInputStream() time: "
				+ (lEndTime - lStartTime) + "ms");
		nTime3Lasts = (int) (lEndTime - lStartTime);
	}

	/**
	 * Read file by buffer array(user-defined buffer) 通过自定义缓冲区读写文件方法
	 * 
	 * @param strFileFrom
	 * @param strFileTo
	 * @throws IOException
	 */
	private void readByUserDefinedBuffer(String strFileFrom, String strFileTo)
			throws IOException {
		long lStartTime = System.currentTimeMillis();

//		InputStream in = null;
//		OutputStream out = null;
//		try {
//			in = new FileInputStream(strFileFrom);
//			out = new FileOutputStream(strFileTo);
//			int availableLength = in.available();
//			byte[] totalBytes = new byte[availableLength];
			byte[] totalBytes = new byte[];
//			int bytedata = in.read(totalBytes);
//			out.write(totalBytes);
//		} finally {
//			if (in != null) {
//				in.close();
//			}
//			if (out != null) {
//				out.close();
//			}
//		}

		// TODO 512MB
		InputStream bis = null;
		OutputStream bos = null;
		try {
			InputStream in = new FileInputStream(strFileFrom);
			bis = new BufferedInputStream(in, 819200);
			OutputStream out = new FileOutputStream(strFileTo);
			bos = new BufferedOutputStream(out);
			int iEOF = -1;
			while ((iEOF = bis.read()) != -1) {
				bos.write(iEOF);
			}
		} finally {
			if (bis != null) {
				bis.close();
			}
			if (bos != null) {
				bos.close();
			}
		}
		//TODO
		
		
		long lEndTime = System.currentTimeMillis();
		System.out.println("readByBufferArray() time: "
				+ (lEndTime - lStartTime) + "ms");
		nTime4Lasts = (int) (lEndTime - lStartTime);
	}

	public void actionPerformed(ActionEvent e) {
		try {
			Object source = e.getSource();
			if (source == jmiCDEMotif) {
				UIManager.setLookAndFeel(CDEMOTIF);
				SwingUtilities.updateComponentTreeUI(jfMain);
			} else if (source == jmiGTK) {
				UIManager.setLookAndFeel(GTK);
				SwingUtilities.updateComponentTreeUI(jfMain);
			} else if (source == jmiMetal) {
				UIManager.setLookAndFeel(METAL);
				SwingUtilities.updateComponentTreeUI(jfMain);
			} else if (source == jmiNimbus) {
				UIManager.setLookAndFeel(NIMBUS);
				SwingUtilities.updateComponentTreeUI(jfMain);
			} else if (source == jmiWindows) {
				UIManager.setLookAndFeel(WINDOWS);
				SwingUtilities.updateComponentTreeUI(jfMain);
			} else {
				UIManager.setLookAndFeel(WINDOWSCLASSIC);
				SwingUtilities.updateComponentTreeUI(jfMain);
			}
		} catch (Exception ex) {
		}
	}

	public static void main(String args[]) {

		try {
			UIManager.setLookAndFeel(NIMBUS);
		} catch (Exception e) {
		}
		rw = new StreamTest();
	}
}

  欢迎讨论指正!^_^

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值