IO实际上就是input & output,解释起来就是输入和输出。
可以从其中读入一个字节序列的对象称作输入流,而可以向其中写入一个字节序列的对象称作输出流。这些字节序列的来源地和目的地可以是文件,而且通常都是文件,但是也可以是网络连接,甚至是内存块。编程语言的I/O类库中使用流这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象。
1、字节流。java.io包中的InputStream和OutputStream两个类及各具体子类,这是Java IO发展过程当中最早就有的内容。
2、字符流。java.io包中的Reader和Writer类以及具体子类。在字节流处理的基础上,封装了编码等内容,提供了字符级别的处理,更方便开发。
3、文件处理。输入输出最基本的就是通过磁盘文件进行,Java IO中的文件处理也很重要。这其中包括File类的使用、FileInputStream/FileOutputStream、RandomAccessFile以及文件的映射和锁定等。
4、Socket相关。除了最基本的文件处理,企业级开发中网络的数据传输在Java IO中有很多要点,而对于网络的输入输出我们都是通过Socket以及其他java.net包中的类进行的。
5、序列化。其实在java.io包中还包含了像Serializable和Externalizable,目的就是方便进行和输入输出相关的序列化和反序列化操作。
简单的理解:流是数据和数据处理过程的统称。
InputStream读取数据源及其对应子类:
1)字节数组 – ByteArrayInputStream
2)String对象 – StringBufferInputStream
3)文件 – FileInputStream
4)“管道”:从一端输入,从另一端输出 – PipedInputStream
5)一个由其他种类的流组成的序列 – ObjectInputStream
6)其他数据源,如音频文件 – AudioInputStream
OutputStream类别的类决定了输出所要去的目标,这些目标包括及其对应子类:
1)字节数组 – ByteArrayOutputStream
2)文件 – FileOutputStream
3)“管道” – PipedOutputStream
1、读取音频文件的AudioInputStream
需求说明:现在我们要用AudioInputStream 读取C:\Users\lenovo\Music目录下的音频文件”逃跑计划 - 夜空中最亮的星.wav“。
File f = new File("C:\\Users\\lenovo\\Music\\逃跑计划 - 夜空中最亮的星.wav");
byte[] b = new byte[1024];
try(AudioInputStream as = AudioSystem.getAudioInputStream(f);){
//将音频文件读取字节数组中
as.read(b);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(b[0]);
2、读取字节数组的ByteArrayInputStream
需求说明:现在我们要用ByteArrayInputStream 读取”F:\1.txt文件”。
byte buf[] = new byte[1024];
byte b[] = new byte[1024];
// 创建一个 ByteArrayInputStream,使用 b作为其缓冲区数组。
try(InputStream is = new FileInputStream("C:/Users/lenovo/Music/Justin Bieber - Love Yourself.mp3");
ByteArrayInputStream bais = new ByteArrayInputStream(b);)
{
is.read(b);
//将数据此输入流读入 byte数组
bais.read(buf);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(buf[0]);
3、写入字节的ByteArrayOutputStream
需求说明:现在我们要用ByteArrayOutputStream 接收输入流中的数据,然后将数据写入字节数组。
int temp = 0;
//创建输入输出流对象
try(InputStream is = new FileInputStream("C:/Users/lenovo/Music/Justin Bieber - Love Yourself.mp3");
ByteArrayOutputStream baos = new ByteArrayOutputStream())
{
//将输入流中的数据写入输出流
while((temp=is.read())!=-1){
baos.write(temp);
}
//将输出流中的数据导出到字节数组中
byte[] b = baos.toByteArray();
System.out.println(b[0]);
} catch (Exception e) {
e.printStackTrace();}
4、读取文件的FileInputStream
需求说明:现在我们要用FileInputStream 将文件中的数据读入字节数组。
byte[] b = new byte[1024];
try(InputStream is = new FileInputStream("F:/1.txt"))
{
//将文件中的数据读入字节数组
is.read(b);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(b[0]);
5.将数据写入文件的FileOutputStream
需求说明:将”1.txt“文件复制到一个指定路径的新文件”2.txt“中。
int temp = 0;
//创建文件读取输出流
try(InputStream is = new FileInputStream("F:/1.txt");
FileOutputStream fos = new FileOutputStream("F:/3.txt"))
{
while((temp=is.read())!=-1){
fos.write(temp);
}
} catch (Exception e) {
e.printStackTrace();
}
6、接受写入管道输出流的所提供的数据字节的PipedInputStream
需求说明:利用PipedInputStream读取管道输出流中的数据。
//创建一个管道输入流
PipedInputStream pis = new PipedInputStream();
byte a[] = new byte[]{1,2,3,4,5,6};
byte b[] = new byte[1024];
//创建一个管道输出流
PipedOutputStream pos = new PipedOutputStream();
//将字节数组写入管道输出流
try{ //将输出流管道与输入流管道连接,不连接将抛出IO
pos.connect(pis);
pos.write(a,0,5);
//刷新管道输入流
pos.flush();
//读取管道输出流中的数据
pis.read(b);
System.out.println(b[0]);
} catch (IOException e) {
e.printStackTrace();
}finally{ //关闭管道输入流和管道输出流
try { pos.close();
pis.close();
} catch (Exception e) {
System.out.println("发生IO异常!");}}
7、将其他输入流逻辑串联,依次读取的SequenceInputStream
需求说明:将两个输入流连接在一起,依次读取两个输入流的数据。
byte[] b = new byte[1024];
try(InputStream is1 = new FileInputStream("F:/1.txt");
InputStream is2 = new FileInputStream("F:/2.txt");
//创建SequenceInputStream对象,将两个输入连接
SequenceInputStream sis = new SequenceInputStream(is1,is2);)
{
//依次读取两个输入流
sis.read(b);
} catch (IOException e) {
e.printStackTrace();}
System.out.println(b[0]);
在进行流操作时,最后一定要将流关闭,基本上每个特定的InputStream类都有对应的OutputStream类,其实不同类在文件的读取和写入上都存在共同点。