JAVAIO

一.什么是JAVAIO?

 

     Java 把 Input输入流 和 Output 输出流,统称为IO流。它的核心就是对文件的操作,对于字节或字符类型的输入和输出。

流的概念和作用:

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在设备间传输称之为流。

流的本质是数据传输,根据数据传输的特性将流区分为各种类,方便更直观的进行数据操作。

 

阻塞型IO和非阻塞型IO(NIO):

阻塞型IO在读取数据时,如果数据未到达,会一直阻塞到读取到数据为止,所以称为阻塞型IO,在高并发的环境下性能不佳。

NIO不是使用 “流” 来作为数据的传输方式,而是使用通道,通道的数据传输是双向的,且NIO的数据写入和读取都是异步的,不会阻塞线程,所以称为非阻塞型IO,在高并发的环境下性能很好。

二.IO流的分类

1.按照流的操作颗粒度划分

e88c91070f9245bf8092e2aa771abd41.jpeg

IO流主要分为两大类,字节流和字符流。字节流可以处理任何类型的数据,如图片,视频等,字符流只能处理字符类型的数据。

学习java的方向是使用Java操作文件系统,那么首先要学习的就是文件的表示,然后我们要操作文件。但是IO流的概念不仅仅局限在操作文件上,我们的编程语言是要能操作所有的输入输出,因此,API提供了两个顶层抽象类,用来表示操作所有的输出输出:InputStream,OutputStream,并且这两个类表示字节的输入输出,因为输入输出的本质是字节流。

2.按照流的输入方向(输入输出都是站在程序所在内存的角度划分)

• 输入流:只能从中读取数据【主要由InputStream和Reader作为基类】

• 输出流:只能向其写入数据【主要由outputStream和Writer作为基类】

3.按照流的角色划分

• 节点流:可以从或向一个特定的IO设备(如磁盘,网络)读/写数据的流,也叫低级流。

• 处理流:用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能,也                    叫高级流。

三.常见的IO流

1.访问操作文件(FileInputStream/FileReader,FileOutputStream/FileWriter)

(1)使用FileInputStream从文件中读取数据

import java.io.*;
public class TestFileInputStream {

	public static void main(String[] args) {
		int b=0;
		FileInputStream in = null;
		try {
		in =new FileInputStream("C:\\Users\\41639\\Desktop\\java\\FileText\\src\\TestFileImportStream.java");
		}catch(FileNotFoundException e){
			System.out.println("file is not found");
			System.exit(-1);
		}
		try {
			long num=0;
			while ((b=in.read())!=-1) {
				System.out.println((char)b);
				num++;
			}
			in.close();
			System.out.println();
			System.out.println("共读取了"+num+"个字节");
		}catch(IOException e) {
			System.out.println("IO异常,读取失败");
			System.exit(-1);
		}
	}

(2)使用FileOutputStream往文件中写数据

import java.io.*;
public class TextFileOutputStream {

	public static void main(String[] args) {
		int b=0;
		FileInputStream in = null;
		FileOutputStream out = null;
		try {
		in =new FileInputStream("C:\\Users\\41639\\Desktop\\java\\FileText\\src\\TestFileImportStream.java");
		out=new FileOutputStream("C:\\Users\\41639\\Desktop\\java\\temp\\out.java");
		}catch(FileNotFoundException e){
			System.out.println("file is not found");
			System.exit(-1);
		}
		try {
			while ((b=in.read())!=-1) {
				out.write(b);
			}
			in.close();
			out.close();
		}catch(IOException e) {
			System.out.println("IO异常,读取失败");
			System.exit(-1);
		}
		System.out.println("文件复制完成");
	}

}

2.缓存流的使用(BufferedInputStream/BufferedOutputStream,BufferedReader/BufferedWriter)

学了文件IO字节流之后,我们会发现原始的字节流对象用起来没那么高效,因为每个读或写请求都由底层操作系统处理,这些请求往往会触发磁盘访问、网络活动或其他一些相对昂贵的操作。不带缓冲区的流对象,只能一个字节一个字节的读,每次都调用底层的操作系统API,非常低效,而带缓冲区的流对象,可以一次读一个缓冲区,缓冲区空了才去调用一次底层API,这就能大大提高效率,因此我们可以使用缓存流。

import java.io.*;
public class TestBufferStream {
	public static void main (String[] args) throws IOException{
		BufferedInputStream bis=null;
		BufferedOutputStream bos=null;
		try {
			FileInputStream fis = new FileInputStream("C:\\Users\\41639\\Desktop\\java\\FileText\\src\\TestFileImportStream.java");
			FileOutputStream fos = new FileOutputStream("C:\\Users\\41639\\Desktop\\java\\temp\\out2.java");
			bis = new BufferedInputStream(fis);
			bos = new BufferedOutputStream(fos);
			byte[] b = new byte[1024];
			int off=0;
			while ((off=bis.read(b))>0) {
				bos.write(b,0,off);
			}
			bis.close();
			bos.close();
		}catch (IOException e) {
			e.printStackTrace();
		}finally {
			bis.close();
			bos.close();
		}		
	}
}

从代码中可以看到,最基本的其实也是FileInputStream和FileOutputStream,在这个“流”的基础上,又加了缓存的功能流BufferedInputStream和BufferedOutputStream。

3.转换流的使用(InputStreamReader/OutputStreamWriter)

转换流是字节流和字符流之间相互转换的桥梁,把字节流转成字符流,离不开转换流,字符流是对于字符功能的增强可用来处理“文字”。

import java.io.*;
public class TransStreamTest {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\41639\\Desktop\\java\\temp\\test1031.txt"));
		String line =null;
		while ((line=br.readLine())!=null) {
			if ("over".contentEquals(line)) {
				break;
			}
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
    bw.close();
    br.close();
	}

}

4、对象流的使用(FileInputStream/ObjectOutputStream)

在程序设计的过程中,我们都是用类和对象来描述定义,能不能直接把对象进行传输。答案当然是肯定的,对象流其实就是一种特殊的处理流水,也是在基础的字节流上去作封装。

下面程序使用一个对象流,把对象直接写到文件中。

import java.io.*;
public class ObjectStreamTest {
	public static void main(String[] args) throws Exception{
		try {
			Person P=new Person("Jeccica",26);
			FileOutputStream fos=new FileOutputStream("C:\\Users\\admin\\Desktop\\Java\\temp\\22.txt");
			ObjectOutputStream oos=new ObjectOutputStream(fos);
			oos.writeObject(P);
			oos.flush();
			oos.close();
		}catch(FileNotFoundException e) {
			e.printStackTrace();
		}catch(IOException e) {
			e.printStackTrace();
		}			
		
		FileInputStream fis=new FileInputStream("C:\\Users\\admin\\Desktop\\Java\\temp\\22.txt");
		ObjectInputStream ois=new ObjectInputStream(fis);
		Person P2=(Person)ois.readObject();
		System.out.println(P2.name+"的年龄为"+P2.age);
	}

}

class Person implements Serializable{
	String name=null;
	int age=0;
	Person(String _name,int _age){
		name=_name;
		age=_age;
	}
}

5、字节数组流的使用(ByteArrayInputStream/ByteArrayOutputStream)【通常结合数据流DataInputStream/DataOutputStream】

我们分析了常见的节点流和常见的处理流等,经常而言我们都是针对文件的操作,然后带上缓冲的节点流进行处理,但有时候为了提升效率,我们发现频繁的读写文件并不是太好,那么于是出现了字节数组流,即存放在内存中,因此有称之为内存流;其中字节数组流也一种节点流;除了节点流外,我们也将学习另外一种处理流,即数据流。数据处理流是用于针对数据类型传输处理的,是一种处理流,即是在节点流之上的增强处理,一般用于序列化和反序列化的时候用到。

import java.io.*;
public class DataStream {
	public static void main(String[] args) {
		ByteArrayOutputStream baos=new ByteArrayOutputStream();//创建字节数组流,同时会在内存里面创建数组
		DataOutputStream dos=new DataOutputStream(baos);//对字节数组流外封装成数据处理流
		try {
			dos.writeDouble(Math.random());//利用数据流里面的写入方法,写一个Double类型的随机数据
			dos.writeBoolean(true);
			ByteArrayInputStream bias=new ByteArrayInputStream(baos.toByteArray());//toByteArray()方法是创建一个新分配的字节数组。数组的大小和当前输出流的大小。这里指的是baos这个字节数组
			System.out.println(bias.available());
			DataInputStream dis=new DataInputStream(bias);
			System.out.println(dis.readDouble());
			System.out.println(dis.readBoolean());		
			dos.close();
			dis.close();
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
}

以上就是我对JAVAIO的初步理解,还望各位指正。


课后总结

通过学长的讲解,我了解了一些预习博客中不完善的知识点,很高兴又学到了很多知识。

1.File类

(1)绝对路径和相对路径

  • 绝对路径:是一个完整的路径,以盘符(C:,D:)开始的路如 C:\\Users\itcast\\IdeaProjects\\shungyuan\\123.txt 
  • 相对路径:

  • 是一个简化的路径,相对指的是相对于当前项目的根目录(c:\lUsers\itcastllIdeaProjectsllshungyuan), 如果使用当前项目的根目录,路径可以简化书写C:\\Users\itcast\\IdeaProjects\\shungyuan\\123.txt-->简化为:123.txt(可以省略项目的根目录)

注意:1.路径是不区分大小写。

2.路径中的文件名称分隔符windows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠。

(2)学会通过api查找file类的方法

 2.System.in&&System.out&&Scanner

Scanner类是JDK1.5中增加的一个类,用于扫描输入文本的实用程序。如果使用Scanner类,必须使用import语句导入Scanner类,位于java.util包中。

System.in作为InputStream类的对象实现标准输入,可以调用它的read方法来读取键盘数据。

System.out作为PrintStream打印流类的的对象实现标准输出,可以调用它的print、println或write方法来输出各种类型的数据。

b29bfc6571c34ea584ed8eaca721728b.png

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值