1.什么是java IO?
通过java一些列文件操作的API,对文件进行读取,写入等操作。即为java IO;这里的文件可以是文本文件,视频,音频,图片等等。
2.什么是IO流
java中操作文件的类,大多叫流(stream)。比如输入的类 InputStream(输入流),输出的类(OutputStream)。为什么叫流呢,其实很形象。比如我们水从一个地方流向一个地方,就形成了水流,而文件呢,是一堆字节。这些字节呢,从硬盘流向程序里面,就形成了一个字节流,即输入流。 而这些类更像一个水管,连接着文件与程序代码。
3.java常用IO类
java中流按流向来分,可以分为两类:
3.1 InputStream:输入流,即将文件读入程序。(文件-->程序,是进入程序,所以为输入流);
3.2 OutputStream:输出流,即将程序中的内容,写入文件。(程序 -->文件 ,是离开程序,所以是输出流)。
4.java 输入流 InputStream
输入流对应的类是InputStream。java API中 ,这是一个抽象类。 其主要的方法有:
- int read() :读取一个字节,并以int形式返回。
- int read(byte b[]) :将数据读取入传入的byte数组中,即byte b[]中。返回值 int 为读取的字节的个数。返回-1则表示已经读取到了文件末尾。
- int read(byte b[], int off, int len) 将数据读取到byte b[]中。起始位置为off,最大读取字节长度为len。
- void close(); 关闭流。 对应的流是会占用系统资源的,当我们读取完后,需要调用close()方法,关闭流。
InputStram 是抽象类,刚才提到的这些方法大多是抽象方法。抽象类只是定义了方法的规范,具体的实现,可能还需要其子类来完成。
InputStream 常用的子类有:
1)FileInputStream: 文件输入流。
2)BufferedInputStream:缓冲输入流。
接下来我们将具体介绍这两个输入流的操作。
4.1 FileInputStream
FIleInputStream 主要用于读取文件内容。常用的两个构造方法为:
1)FileInputStream(String name) name为文件的全路径(包含文件名)
2)FileInputStream(File file) file为文件对象
代码示例:
/**
* 测试read 方法
* @throws IOException
*/
@Test
public void read() throws IOException {
//FileInputStram 的常用构造方法
//1) FileInputStream(String name) name为文件的全路径(包含文件名)
//2)FileInputStream(File file) file为文件对象
//通过构造方法1)创建对象
FileInputStream fileInputStream=new FileInputStream("E:/java.txt");
//读取一个字节
int i=fileInputStream.read();
//内容为字节的int值
System.out.println(i);
//将字节转换为char ,如果他是英文的话(占一个字节),即可看到内容。
char a=(char)i;
System.out.println(a);
//定义一个数组来存放读取到的字节
byte[] bytes={};
//通过read()方法读取全部内容
int b=0;
//当存在中文时,一个一个读取,然后打印就会出现乱码的情况
while((b=fileInputStream.read())!=-1){
System.out.println((char)b+":"+b);
bytes=Arrays.copyOf(bytes,bytes.length+1);
bytes[bytes.length-1]=(byte) b;
}
String str=new String(bytes);
System.out.println(str);
//关闭流
fileInputStream.close();
}
/**
* 通过read(byte[] b)一次性读取到byte[]数组中
* @throws IOException
*/
@Test
public void readByteArray() throws IOException {
//通过构造方法2)创建对象
File file=new File("E:/java.txt");
FileInputStream fileInputStream=new FileInputStream(file);
//创建字节数组来接收读取到的内容
byte[] bytes=new byte[(int)file.length()];
//一次性读取bytes.length个数组。
fileInputStream.read(bytes);
//如果编码不是当前项目编码,则指定编码格式
System.out.println(new String(bytes,"GB2312"));
//关闭流
fileInputStream.close();
}
5.java中输出流
输出流对应的java中的OutputStream。同InputStream类似,OutputStream同样是一个抽象类。主要作用就是写文件,将内容写入文件中。常见的方法有:
- void write(int b):写入一个字节。
- void write(byte b[]) :写入一个字节数组。
- void write(byte b[], int off, int len):写入字节数组内容,开始位置为off,长度为len。
- void close():关闭流。
- void flush(): 清理缓冲内容,将内容全部写入文件。
OutputStream中常用的子类有:
- FileOutputStream :文件输出流,用于写文件。
- BufferedOutputStream:字节缓冲输出流。
5.1 FileOutputStream 文件输出流
代码示例:
/**
* write方法:向文件中写单个字节
*/
@Test
public void write() throws IOException {
File file=new File("E:/a.txt");
FileOutputStream out=new FileOutputStream(file);
//写入单个字节
char a='a';
out.write(a);
out.write(97);
out.write(98);
char num=49;
out.write(num);
//写一段话的话 需要循环写
String str="hello!你好。\n我是FileOutputStream 写入的一段话";
byte[] bytes=str.getBytes();
for(byte b:bytes){
out.write(b);
}
//清理缓存
out.flush();
//关闭流
out.close();
}
/**
* 写入byte数组
*/
@Test
public void writeByteArray() throws IOException {
String str="我是通过write(byte[]b)写入的内容";
FileOutputStream fos=new FileOutputStream("E:/a.txt");
fos.write(str.getBytes());
fos.flush();
fos.close();
}
@Test
public void writeByArrayWidthParam() throws IOException {
String str="我是通过write(byte[]b,int offset,int len)方法写入的内容";
File file=new File("E:/a.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write(str.getBytes(),10,str.getBytes().length-10);
fos.flush();
fos.close();
}
OK! 相信通过FileInputStream 和FileOutputStream的例子呢,大家应该都大概知道了文件的输入操作,输出操作该怎么弄啦,大致的方法是什么。
我们接下来呢,就通过FileInputStream 和FileOutputStream来实现一个文件的复制操作。
public static void fileCopy(String from,String to){
FileInputStream fis=null;
FileOutputStream fos=null;
try {
fis=new FileInputStream(from);
fos=new FileOutputStream(to);
byte[] buffer=new byte[1024];
int size=0;
while((size=fis.read(buffer))!=-1){
fos.write(buffer,0,size);
fos.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fos!=null){
fos.close();
}
if(fis!=null){
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
fileCopy("D://a//test.java","D://a//a.java");
}
6.字符流
前面讲到的字节流,处理文本文件还是不是很方便。于是java提供了Reader和Writer。字符输入和输出流,来完善文本文件的读取与写入操作。
字符流是以字符为单位读取文件的。
6.1 InputStreamReader
public class FileReaderAndWriterTest {
public static void readFile(String filePath){
FileReader fr=null;
try {
fr=new FileReader(filePath);
char [] buffer=new char[1024];
int size=0;
while ((size=fr.read(buffer))!=-1){
for (int i=0;i<=size;i++){
System.out.println(buffer[i]);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void fileWriter(String filePath){
FileWriter writer= null;
try {
writer = new FileWriter(filePath,true);
writer.write("\r\n我是FileWriter写入的内容第三行");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void bufferedReaderTest(String path){
BufferedReader br=null;
try {
br=new BufferedReader(new FileReader(path));
String str=null;
while ((str=br.readLine())!=null){
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (br!=null){
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// readFile("D://a//b.txt");
// fileWriter("D://a//b.txt");
bufferedReaderTest("D://a//b.txt");
}
}
7.序列化与反序列化
把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
对象的序列化主要有两种用途:
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
transient 修饰的属性和static修饰的属性不会被序列化
在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
public static void serziableTest(){
User user=new User();
user.setName("张三");
user.setAge(12);
user.setBirthday(new Date());
try {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D://a//c.txt"));
oos.writeObject(user);
oos.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readObject() {
try {
FileInputStream fis = new FileInputStream("D://a//c.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
//判断是否到文件末尾
while (fis.available() > 0) {
User u = (User) ois.readObject();
System.out.println(u);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
serziableTest();
readObject();
}