Java学习笔记(五)-- IO流(1)
1. Java IO流概述
Java中I/O操作主要是指使用java.io
包下的内容,进入输入、输出操作。
输入:也叫做读取数据
输出:也叫做写出数据
1.1 IO的分类
按数据的流向分为:
- 输入流:把数据从***其他设备***读到***内存***中的流。
- 输出流:把数据从***内存***中写出到***其他设备***上的流
按数据的类型分为:字节流和字符流
1.2 顶级父类
输入流 | 输出流 | |
---|---|---|
字节流 | 字节输入流 InputStream | 字节输出流 OutputStream |
字符流 | 字符输入流 Reader | 字符输入流 Writer |
2. 字节流
一切文件数据(文本、图片、视频)等在存储时,都是以二进制数字的形式保存,为一个一个的字节。在传输过程时也是一样。字节流可以传任意的数据。在操作流的时候,需要明确,无论是用什么流对象,在底层传输的都是二进制数据。
2.1 字节输出流(OutputStream)
Java.io.OutputStream
抽象类是表示字节输出流的所有类型的超类。它定义了字节输出流的基本共性功能方法
public void close()
:关闭输出流并释放与此流有关的任何系统资源
public void flush():刷新此输出流并强制任何缓冲的输出字节被写出
public void write(byte[] b)
:将b.length字节从指定的字节数据组写入此输出流
public vlid write(byte[] b, int off, int len)
:从指定的字节数组写入len字节,从偏移量off开始输出 到此输出流
public abstract void write(int b)
:将指定的字节输出到输出流
2.2 FileOutputStream
文件字节输出流,OutputStream实现类之一。
1. 作用:把内存中的数据写入到硬盘中。
2. 构造方法:
FileOutputStream(String name)
创建文件输出流以指定的名称写入文件。FileOutputStream(File file)
创建文件输出流以写入由指定的File
对象表示的文件。FileOutputStream(String name, boolean append)
创建文件输出流以指定的名称写入文件。FileOutputStream(File file, boolean append)
创建文件输出流以写入由指定的File
对象表示的文件。FileOutputStream(FileDescriptor fdObj)
创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
3. 字节输出流的使用步骤:
1)创建一个FileOutputStream对象,构造方法中传递写数据的目的文件
2)调用FileOutputStream对象中的Write访求以,把数据写入到文件中。
3)使用完成要释放资源,使用close方法。
4. 写出字节数据
写入数据的原理(内存–>硬盘):java程序–>JVM(Java虚拟机)–> OS(操作系统)–>OS调用写数据方法–>数据写入文件
write(int b)
:每次写出一个字节
public class FosWrite{
public static void main(String[] args) throws IOException{
FileOutputStream fos=new FileOutputStream("fos.txt");
fos.write(97);
fos.write(98);
fos.close();
}
}
说明:
1)写数据时,把10进制的整数97转为二进制的97,即01100001。文件保存时,会保存1个字节即8个比特位。使用文本编辑器时,如记事本,会检查编码表,把字节转化为字符表示。其中:
2)0-127使用ASCII码表。ASCII码表中97->a
3)其他值查询系统默认码表,针对中文系统,检查GBK码表。GBK码表一个汉字占两个字节。UTF-8码表一个汉字占三个字节。对于汉字,每个字节是以1开头,即为负数
- 一次写多个字节
使用父类OutputStream中定义的方法:
public void write(byte[] b)
:将b.length字节从指定的字节数据组写入此输出流
public vlid write(byte[] b, int off, int len)
:从指定的字节数组写入len字节,从偏移量off开始输出
public class FosWrite{
public static void main(String[] args) throws IOException{
FileOutputStream fos=new FileOutputStream("fos.txt");
byte[] bytes={65,66,67};
//fos.write(bytes,1,2);
fos.write(bytes);
fos.close();
}
}
可以使用String.getBytes()
,如"这是数据".getBytes()
将中文字符串转化为字节数组,并使用write(byte[] b)
输出中文。
- 数据的追加和换行
数据追加
使用构造函数:
FileOutputStream(String name, boolean append)
创建文件输出流以指定的名称写入文件。FileOutputStream(File file, boolean append)
创建文件输出流以写入由指定的File
对象表示的文件。
设置构造函数中append参数,true
表示追加数据,保持原文件中数据并在后追加。false
表示覆盖原文件数据,将原文件数据清空。
换行写入
写换行符以输出换行
Windows系统:\r\n
Linux系统:/n
Mac系统:/r
2.3 字节输入流(InputStream)
Java.io.InputStream
抽象类是表示字节输入流的所有类型的超类。它定义了字节输入流的基本共性功能方法
public void close()
:关闭输入流并释放与此流有关的任何系统资源public abstract int read()
:从输入流读取数据的下一个字节public int read(byte[] b)
:从输入流中读取一些字节,并保存到字节数组b中
2.4 FileInputStream类
文件字节输入流,InputStream实现类之一
**1. 作用:**从文件中读取字节到内存
2. 构造方法
FileInputStream(File file)
通过打开与实际文件的连接创建一个FileInputStream
,该文件由文件系统中的File
对象file
命名。FileInputStream(FileDescriptor fdObj)
创建FileInputStream
通过使用文件描述符fdObj
,其表示在文件系统中的现有连接到一个实际的文件。FileInputStream(String name)
通过打开与实际文件的连接来创建一个FileInputStream
,该文件由文件系统中的路径名name
命名
3. 字节输入流使用步骤
1)创建FileInputStream对象,构造方法参数确定要读取的文件。
2)使用FileInputStream对象中的方法read,读取文件。
3)使用完成释放资源,使用close方法。
4. 读取数据
读取数据的原理(硬盘–>内存):java程序->JVM(Java虚拟机)->OS(操作系统)->OS读数据方法->读取文件
读取开始,指针指向文件头。使用read方法,读取下一个字节(即第1个字节代表的A)后,指针后移一字节。
- 读取一个字节:
int read()
: 返回读取的一个字节的数据。读取到末尾,返回-1。
public class FisRead{
public static void main(String[] args) throws IOException{
FileInputStream fis=new FileInputStream("fos.txt");
int len=fis.read();
System.out.println(len);//显示的是一个字节对应的数字如97 a
fos.close();
}
}
如读取文件到末尾,没有新的字节读取返回-1。可以通过循环,每次读取一个字节直到读取完
public class FisRead{
public static void main(String[] args) throws IOException{
FileInputStream fis=new FileInputStream("fos.txt");
int len=0;
while((len=fis.read())!=-1){//判断读取的字节不是-1,即不是文件末尾
System.out.println(len);
}
fos.close();
}
}
对于ASCII码字符,如英文、数字等,可以使用char
转换显示出字符,如System.out.println((char)len)
- 一次读取多个字节
int read(byte[] b)
:读取字节并保存到数组中,返回int为读取多少字节数
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("D:\\test.txt");
byte[] bytes= new byte[1024];
int len=0;
while ((len=fis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
fis.close();
}
}
说明:
1) 使用byte[] 数组方式保存每次读取的字节,起到缓冲作用。byte[]数组大小一般定义为1024或1024的整数倍。
2) len为read(byte[] b)方法返回的读取字节个数。没有读取到,返回-1。
3)使用String类构造方法将byte[]数组转换为字符串:
new String(byte[])
:将字节数组转为字符串
new String (byte[] b, int off, int len)
:将读取的字节数组转为字符串。off 为数组的开始索引,在这里起始为0,len为转换的字节个数,在这里为读取的字节数。
2.5 复制文件
package JavaStudy.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("D:\\test.jpg");
FileOutputStream fos=new FileOutputStream("d:\\test1.jpg");
byte[] bytes=new byte[1024];
int len=0;
while((len=fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
fos.close();
fis.close();
}
}
以上代码均不处理异常,直接向上抛出。