[javase]IO之InputStream

InputStream,抽象类,字节输入流

一、AudioInputStream

AudioInputStream 是音频输入流,支持的文件格式有wav,au,和aiff。

示例代码

package com.javanet.io;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;

import org.junit.Test;

public class TestInputStream extends JFrame {
	
	@Test
	public void testAudioInputStream() {
		File file;
		AudioInputStream ais = null;
		AudioFormat format;
		DataLine.Info info;
		SourceDataLine sdline = null; 
		try {
			
			file = new File("D://Music//17.wav");
			ais = AudioSystem.getAudioInputStream(file);
			format = ais.getFormat();
			info = new DataLine.Info(SourceDataLine.class, format);
			sdline = (SourceDataLine) AudioSystem.getLine(info);
			sdline.open(format);
			sdline.start();
			
			int nBytesRead = 0;
			byte[] abData = new byte[524288];
			while (nBytesRead != -1) {
				nBytesRead = ais.read(abData, 0, abData.length);
				if (nBytesRead >= 0) {
					sdline.write(abData, 0, abData.length);
				}
			}
			
			
		} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
			e.printStackTrace();
		} finally {
			try {
				ais.close();
				//auline.drain()和auline.close()用来保证该声音文件播放完毕,如果去掉会出现声音未播放完即结束的情况。
				sdline.drain();
				sdline.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	@Test
	public void clipTest() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        this.setTitle("Test Sound Clip");  
        this.setSize(300, 200);  
        this.setVisible(true);
		
        try {  
        	  
            // Open an audio input stream.  
            // URL url = this.getClass().getResource("hello.wav");  
            File file = new File("D://Music//17.wav");  
  
            // AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);  
            AudioInputStream audioIn = AudioSystem.getAudioInputStream(file);  
            // Get a sound clip resource.  
            Clip clip = AudioSystem.getClip();  
            // Open audio clip and load samples from the audio input stream.  
            clip.open(audioIn);  
            clip.start();  
        } catch (UnsupportedAudioFileException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (LineUnavailableException e) {  
            e.printStackTrace();  
        }  
	}
	
	public static void main(String[] args) {
		new TestInputStream().clipTest();
	}

}
二、ByteArrayInputStream

ByteArrayInputStream 是字节数组输入流。它继承于InputStream。
它包含一个内部缓冲区,该缓冲区包含从流中读取的字节;通俗点说,它的内部缓冲区就是一个字节数组,而ByteArrayInputStream本质就是通过字节数组来实现的。
我们都知道,InputStream通过read()向外提供接口,供它们来读取字节数据;而ByteArrayInputStream 的内部额外的定义了一个计数器,它被用来跟踪 read() 方法要读取的下一个字节。

示例代码

@Test
public void byteArrayInputStreamTest() throws IOException {
	
	byte[] buf = "xiaoming".getBytes();
	ByteArrayInputStream bais = new ByteArrayInputStream(buf);
	int b;
	while ((b =bais.read()) != -1) {
		System.out.println(b);
	}
	bais.close();
}

三、FileInputStream

FileInputStream 是文件输入流,多用于读取图像等数据的原始字节流,如读取字符流,请使用FileReader

示例代码

@Test
public void fileInputStreamTest() {
	
	File file;
	FileInputStream fis = null;
	FileOutputStream ost = null;
	try {
		file = new File("D://Music//youdian.flac");
		fis = new FileInputStream(file);
		
		ost = new FileOutputStream("D://Music//youdian.mp3");
		
		byte[] buff = new byte[100];
		int copySize;
		while ((<span style="font-family:Arial, Helvetica, sans-serif;">copySize </span>= fis.read(buff)) != -1) {
			ost.write(buff);
		}
		
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		if (fis != null) {
			try {
				ost.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
四、FilterInputStream

FilterInputStream 的作用是用来“封装其它的输入流,并为它们提供额外的功能”。它的常用的子类有BufferedInputStream和DataInputStream。

1、BufferedInputStream

BufferedinPUTBufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。

因此,当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。
BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。
BufferedOutputStream和FileOutputStream同理,差异更明显一些。

@Test
public void BufferedInputStreamTest() {
	
	File file;
	BufferedInputStream bis = null;
	BufferedOutputStream bos = null;
	try {
		file = new File("D://Music//youdian.flac");
		bis = new BufferedInputStream(new FileInputStream(file));
		
		bos = new BufferedOutputStream(new FileOutputStream("D://Music//youdian.mp3"));
		
		byte[] buff = new byte[100];
		int copySize;
		while ((copySize = bis.read(buff)) != -1) {
			bos.write(buff, 0, copySize);
		}
		bos.flush();
		
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		try {
			if (bos != null) {
				bos.close();
			}
			if (bis != null) {
				bis.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
2、DataInputStream

DataInputStream 是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。应用程序可以使用DataOutputStream(数据输出流)写入由DataInputStream(数据输入流)读取的数据。

@Test
public void dataInputStreamTest() {
	
	DataInputStream dis = null;
	DataOutputStream dos = null;
	try {
		
		dos = new DataOutputStream(new FileOutputStream(new File("d://music/xiaoming3.txt")));
		dos.writeUTF("哈喽!");
		dos.writeBoolean(true);
		dos.writeDouble(10.02);
		dos.writeBytes("小明");
		
		dis = new DataInputStream(new FileInputStream(new File("d://music//xiaoming3.txt")));
		System.out.println("readUTF: " + dis.readUTF());
		System.out.println("readBoolean: " + dis.readBoolean());
		System.out.println("readDouble: " + dis.readDouble());
		System.out.println("readBytes: " + dis.read());
		
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		try {
			if (dos != null) {
				dos.close();
			}
			if (dis != null) {
				dis.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}
四、ObjectInputStream

ObjectInputStream 与 ObjectOutputStream这两个包装类可用于输入流中读取对象类数据和将对象类型的数据写入到底层输入流 。ObjectInputStream 与 ObjectOutputStream 类所读写的对象必须实现了 Serializable 接口。需要注意的是:对象中的 transient 和 static 类型的成员变量不会被读取和写入

class UserBean implements Serializable {

	private static final long serialVersionUID = 1L;
	
	private String username;
	private String sex;
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	
}
@Test
public void objectInputStreamTest() {
	
	List<String> list = new ArrayList<>();
	list.add("xiaoming");
	list.add("大红!");
	
	ObjectOutputStream oos = null;
	ObjectInputStream ois = null;
	try {
		/**
		oos = new ObjectOutputStream(new FileOutputStream(new File("d://music/object.obj")));
		oos.writeObject(list);
		
		ois = new ObjectInputStream(new FileInputStream(new File("d://music/object.obj")));
		List<String> lists = (List<String>) ois.readObject();
		
		 * 输出结果:
		 * xiaoming
		 * 大红!
		 
		for (int i = 0; i < lists.size(); i++) {
			System.out.println(lists.get(i));
		}
		*/
		UserBean userBean = new UserBean();
		userBean.setUsername("小明");
		userBean.setSex("男");
		oos = new ObjectOutputStream(new FileOutputStream(new File("d://music/object.obj")));
		oos.writeObject(userBean);
		
		ois = new ObjectInputStream(new FileInputStream(new File("d://music/object.obj")));
		UserBean ub = (UserBean) ois.readObject();
		//输出结果:username:小明 sex:男
		System.out.println("username:"+ub.getUsername()+" sex:"+ub.getSex());
		
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	} finally {
		try {
			if (ois != null) {
				ois.close();
			}
			if (oos != null) {
				oos.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

五、PipedInputStream

管道流,用于线程间的通信。一个线程的PipedInputStream对象从另外一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。










你可能感兴趣的:([javase]IO之InputStream)