JAVA 文件IO
IO指的是对数据的传输方式,JAVA中数据的传输方式主要以流的方式进行,可以将流理解为水管,而数据就是水管中的水,其中水管还包含阀门,这些阀门就是水管可以调用的方法,也就是流调用相应的方法将数据从一端传输到另一端。其中所处的立场不同,得到输入和输出也不同。如下图所示,所占的立场不同,就会得到不同的输入和输出,选择不同的流。但是我们通常站在程序的立场上。
JAVA的IO操作类在java.io包下面,大概有80个类,但是可以按照传输数据的格式和传输数据的方式分为以以下四类:
- 基于字节操作的 I/O 接口:InputStream 和 OutputStream
- 基于字符操作的 I/O 接口:Writer 和 Reader
- 基于磁盘操作的 I/O 接口:File
- 基于网络操作的 I/O 接口:Socket
以上提到的这些类或接口是抽象类,因此并不提供相应的方法,实现的方法由它的具体子类提供。其中字节流一般以-stream结尾,而字符流一般以-er结尾。流操作操作的数据主要有两种,一种是磁盘(file),也就是文件,另一种是网络(socket)。操作方式分别为读写文件数据和接收和发送网络数据。 - 文件I/O input:读文件;output:写文件
- 网络I/O input:接收数据;output:发送数据
对于网络I/O,将不会在这里进行详细描述,会出一篇详细的文章说明。对于文件数据的传输,常用的流有InputStream、OutPutStream、FileInputStream和FileOutStream。我们都知道任何文件在计算机种都是以二进制进行存储的,即0,1。图片、文本、音频和视频文件在计算机中都会通过编码(encode)为二进制码,文件由这种二进制码组成。这种数据类型叫作字节,一个文件的大小可以通过字节数来衡量,所以数据是字节的集合,因此任何类型的文件都是字节的集合,通过创建字节数组来存储数据。
数据的写入:
//将字符串“你好啊”写入文件 String str ="你好啊"; byte [] data=str.getbyte();//将字符串转化为字节,存进字节数组中 File file=new File("D:\abc.txt"); OutputStream out=new OutputStream(file); out.writr(data,0,data.length); out.close(); //注意:Fie仅表示文件路径,。FileOutputstream才是真的创建文件。 //write方法指的是将字节数组中的第一位到第n位的数据写入文件中
打开文件
outputStream=new FileOutputStream(file); //如果目标文件不存在,则创建新的文件;如果目标文件已经存在,则覆盖文件内容。
数据的读取
byte []data=new byte[100];//data数组用来存储字节数据 InputStream in=new FileInputStream("D:\\abc.txt");//读取当前目录文件里的数据 int a=outputStream.read(data,0,90);//将数据读取到字节数组中,最多可读取90字节 //注意: //a代表实际读取到的字节数 //read方法指的是将数据读取到data数组中,所占的大小为90字节
文本的写入
文本内容不是字节,而是字符,因为文件中只能写入字节数据,所用要将字符转化为字节,把String转成byte[]。
String str="hello";//定义hello字符串 byte[] data=str.getBytes("UTF-8");//将字符串通过getByte()方法,以UTF-8为字符编码参数,将字符编译为字节存进字节数组中 //注意:UTF-8为字符编码参数,常见的有GBK/UTF-8,在UTF-8编码下,一个英文字符对应一个字节,一个中文对应2-3个字节。
文本的读取
//从文件读取数据到data,将data转成String String str=new String(data,0,n,"UTF-8");//从data中读取第一个到第n个字节 //注意:写入时使用UTF-8编码,读取的时候也得使用UTF-8
补充一些常见的字符编码:
- ASCII:用1个字节表示一个字符
- GBK:用2个字节表示一个字符
- UTF8:用1-3个字节表示一个 Unicode字符
- UTF-16:用2个字节表示一个 Unicode字符
- UTF-32:用4个字节表示一个 Unicode字符
- 将一些常见的数据类型写入文件(二进制编码)*
//1创建一个编码器,容量为1000字节 ByteBuffer bbuf=ByteBuffer.allocate(1000);//ByteBuffer编码器将其他数据编码为字节码 //2填入一些基本数据类型 bbuf.putInt(a); bbuf.putDouble(b); bbuf.putShort(c); bbuf.putChar(d); bbuf.putFloat(e); 注意:使用ByteBuffer编码器,可以实现二进制编码,如果要存储到文件,只需要将byte[]存储到文件即可
ByteBuffer四个重要属性
ByteBuffer常用方法
put:写入数据时,写入一个字节数据,position向后移动一位。
get:读取数据时,读取一个字节数据,position向后移动一位。
flip:数据写入完毕后,要读取数据时,将position回到0的位置。
clear:写完数据,需要开始读的时候,将postion回到0,并将limit设为当前postion。
mark&reset:用于标记数据和回到标记位置
//内部指针的位置 int size=bbuf.position(); //内部的数组 byte[] data =bbuf.array(); //内部数组的容量 int capacity=bbuf.capacity();
将字节数据byte[]恢复为原始数据(二进制解码)
//1包装一个buffer,对其中数据进行解码 ByteBuffer.wrap(buffer,off,size); //2设置指针位置 bbuf.position(0); //3提取数据 int a=bbuf.getInt(); duble b=bbuf.getDouble();
allocate和wrap的区别
allocate():内部自己创建一个byte[];wrap():利用外部现成的byte[]。
思考一下如何将一个student类型的对象写入文件中,student对象包含的属性有学号、姓名、性别和手机号码。提示:无论任何对象,都需要编码为byte[],因为文件只能存储byte[]。
int id; String name; boolean sex; String phone; }
未完待续