简介
在java中,数据的输入输出都是以流的方式来处理。
流(Stream
),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道。
JDK中与输入/输出有关的包和类都放在java.io包里面,其中有5个重要的抽象类。
- InputStream :以此结尾的都是字节输入流
- OutputStream :以此结尾的都是字符输出流
- Reader :以此结尾的都是字符输入流
- Writer :以此结尾的都是字符输出流
- File
IO流可按照一下三个方面划分
- 按数据流的方向:输入流、输出流
- 按处理数据单位:字节流、字符流
- 按功能:节点流、处理流
字节流:操作的单元是数据单元为8位的字节
字符流:操作的单元是数据单元为16位的字符
Java的字符采用的Unicode标准,在这里面一个英文是一个字节,一个中文是两个字节
Java中最基本的流就是字节流,但是为了更方便的处理双字节的中文字符,java推出了字符流,
提供了Reader,Writer类及其之类,可以方便的实现字节流和字符流的相互转换、字符流的读/写等等操作。
字符流和字节流的区别:
- 字节流一般用来处理图像、视频、音频、PPT、Word等类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,但不能处理图像视频等非文本文件。用一句话说就是:字节流可以处理一切文件,而字符流只能处理纯文本文件。
- 字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高。而字符流本身就带有缓冲区,缓冲字符流相对于字符流效率提升就不是那么大了。详见文末效率对比
关于其他的还有什么缓冲流之类的之后用到了再回来补充
完整IO分类图:
File类
File类可以用于获取和处理与磁盘文件和文件夹相关的信息和操作,对文件内容的存取通常由
FileInput、FileOutputStream、FileReader、FileWriter等类实现。
File是对文件和文件夹的一种抽象表示(引用或指针)。File类的对象可能指向一个存在的文件或文件夹,也可能指向一个不存在的文件或文件夹。
public class test {
public static void main(String[] args) {
File f=new File("src\\chap_IO\\test.java");
System.out.println("f.exists()="+f.exists()); //判断指向文件是否存在
System.out.println("f.isDirectory()="+f.isDirectory()); //判断指向的是不是文件夹或者说目录
System.out.println("f.length()="+f.length()); //输出指向文件的内容长度
System.out.println("f.getName()="+f.getName()); //获取指向文件或文件夹的名字
System.out.println("f.getParent()"+f.getParent()); //获取到上一级位置的路径
System.out.println("f.getPath()"+f.getPath()); //获取当前文件所在路径
File f1=new File("src\\chap_IO\\hb\\hd");
//mkdirs可以一次性创建多个嵌套文件夹
f1.mkdirs();
File f2=new File("src\\chap_IO\\hc\\dp.txt");
//mkdir一次只能创建一个文件夹
f2.mkdir();
}
}
输出如下所示
IO流的使用
文件字节流(FileInputStream和FileOutStream)
FileInputStream用于从本地文件系统中的一个文件读取直接数据,但并不适合读取文本文件中的字符信息,若含有中文字符,则容易出现乱码。
如下代码利用字节流实现的文件的复制。
package chap_IO;
import java.io.*;
public class test {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("H:\\天天相册\\Elf1-1.mp4");
FileOutputStream fos=new FileOutputStream("H:\\天天相册\\里番\\Elf1-1.mp4"); //这里这个文件是不存在的,传的时候会自动创建
System.out.println("文件大小:"+fis.available());
// 1.一个字节一个字节的读/写,直到文件结尾-1,效率低
// int b=0;
// while((b=fis.read())!=-1) //一个字节一个字节传太慢了,我174mb的视频估计都要传个10多分钟。
// {
// fos.write(b);
// }
// fis.close();
// fos.close();
// 2.一次读取一个数组的数据,效率高
int b=0;
byte[] ba=new byte[1024]; //1mb的大小一两秒就传完了,但是我的视频却放不了了,悲
while((b=fis.read(ba))!=-1)
{
fos.write(ba,0,ba.length-1);//指定数组以及数组的长度
}
fis.close();
fos.close();
}
}
第一种方法传的慢,但是传的视频确实可以播放,第二种方法传的快但是直接损坏视频了,
不清楚传别的ppt之类的东西会不会损坏。
文件字符流(FileReader和FileWriter)
InputStreamReader是字节流通向字符流的桥梁。
InputStreamReader可以使用指定的charset将读取的字节流解码为字符流。为了进一步提高读取数据的效率,可以将字符流包装为BufferedReader类,举例如下:
InputStream is =new FileInputStream("H:\\天天相册2\\天使\\天使☆纷扰 RE-BOOT!\\游戏启动必看.txt");
Reader r=new InputStreamReader(is,"UTF-8");
BufferedReader br=new BufferedReader(r);
String s=br.readLine();
System.out.println(s);
输出如下:
文档内容其实不止这么点,但是这个只读取了第一行,所以只输出了这点。
利用文件字符流实现文件的复制。
利用FileReader和RileWriter实现文件复制功能
public class test {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("C:\\Users\\Administrator\\Desktop\\名单.txt");
FileWriter fw=new FileWriter("C:\\Users\\Administrator\\Desktop\\名单备份.txt");
// 1.一个字符一个字符的读写,直到读到文件尾时返回-1,效率低下
// 这里还不能读取中文,会乱码的
// int ch=0;
// while((ch=fr.read())!=-1)
// {
// fw.write((char)ch);
// }
// fr.close();
// fw.close();
//2.一次读取一个字符数组,效率更高
char[] ca=new char[1023];
int n=0;
while((n=fr.read(ca))!=-1)
{
fw.write(ca,0,ca.length-1);
}
fr.close();
fw.close();
}
}
利用带缓冲区的字符流实现文件的复制
使用BufferedReader和BufferedWriter实现文件的复制功能,效率更高,操作更加简便。
还是会乱码。
public class test {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("C:\\Users\\Administrator\\Desktop\\名单.txt");
BufferedReader br=new BufferedReader(fr);
FileWriter fw=new FileWriter("C:\\Users\\Administrator\\Desktop\\名单备份.txt");
BufferedWriter bw=new BufferedWriter(fw);
String s;
while((s=br.readLine())!=null)
{
System.out.println(s);
bw.write(s);
bw.newLine();
}
bw.flush();
fr.close();fw.close();
br.close();bw.close();
}
}
以上使用文件字节流和文件字符流的输入输出还没解决中文乱码问题,等之后有空了想起来再回来解决。