java对文件的读写通过”流“实现
一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。
下图是一个描述输入流和输出流的类层次图。
可看到流分为字节流和字符流:
字节流:按字节对文件中的内容进行读取,可以对任意类型文件进行访问( 图片视频都可!)
例:
读取文件中的汉字“流” 就是读取了两个字节
一个字符char为两个字节 数字int为4个字节
Java采用unicode来表示字符,java中的一个char是2个字节,一个中文或英文字符的unicode编码都占2个字节,但如果采用其他编码方式,一个字符占用的字节数则各不相同。
字符流:以字符为单位进行读取,一个汉字,一个数字都是一个字符
这种流只能对特定文件读取 如txt文件
word都不行 因为其中有格式 已经不是一个单纯的文本文件了
另外:对字符流的写入时有缓冲区的概念
重要的类:
带有stream的都是字节流
FileInputStream
public class FileInputStreamtest {
public static void main(String[] args) {
FileInputStream fis=null;
//变量需要在try外部声明 在内部为局部变量 就不能在finally出调用相关方法了
try {
//此程序对一个文件进行不断读取 第一个方法已经读完了!对比方法 注意删减!
// 注意!读取文字时如果因为bytes数组的限制只读取了一个字符(汉字为2字符大小)
//会乱码!
fis=new FileInputStream("E:\\test.txt");
//第一种读取 直接调用read 返回int 为读取的字符的编码 a->97
//为空返回-1
int readDate=0;
while ((readDate=fis.read())!=-1){
System.out.println(readDate);
}
//第二种读取 用byte数组 存储的是字符的编码存在数组中,返回成功读取字符的个数
//如果一次没有读完 即数组容量比较小 返回的自然是容量大小;
//如果再用此数组去接收读取的字符时 会从数组的开始进行覆盖
//一次读取完的话 返回读取到的个数
byte[] bytes=new byte[20];
while(true){
int readCount=fis.read(bytes);
if (readCount==-1){
break;
}
//tips://可以将byte数组转为string 将存取的字符的编码编回去 97->a
//从bytes数组的0开始到readCount结束 将这些字符的编码转为字符串
System.out.println(new String(bytes,0,readCount));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//不管之前有没有成功打开 最后都需要关闭 所以为了防止空指针异常 要判断
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
int thelast=fis.available();//返回剩下几个字符没有读
long skipnum=fis.skip(2);//跳过n个不读
FileOutStream
public class FileOutStreamTest {
public static void main(String[] args) {
FileOutputStream fos=null;
try {
// 先清空 再重写
// fos=new FileOutputStream("FileIO/fileIO");
// byte[] bytes={97,98,99,100};
// fos.write(bytes);
// fos.write(bytes,0,2);//长度2
//追加写入
fos=new FileOutputStream("FileIO/fileIO",true);
byte[] bytes={97,98,99,100};
fos.write(bytes);
fos.write(bytes,0,2);
String s="将字符串写入";
byte[] bs=s.getBytes();
fos.write(bs);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
利用流复制文件 (任何格式文件,jpg,mp3…)
public class FileCopy {
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//目录自己设置
fis=new FileInputStream("FileIO/fileIO");
fos=new FileOutputStream("FileIO/CopyedFile.txt");
byte[] bytes=new byte[1024*1024];//1M
int readcCount=0;
while ((readcCount=fis.read(bytes))!=-1){
fos.write(bytes,0,readcCount);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//分开try 防止一个失败另一个也失败
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileReader和FileWriter与以上类似
差别为使用char[]对数据存储,针对普通文本文件
另外对于FileWriter:
public class FileWriterTest {
public static void main(String[] args) {
FileWriter out=null;
try {
out=new FileWriter("FileIO/Filewriter");
char[] chars={'输','出','字','符','串'};
String s="第二个字符串";
out.write(chars);
out.write("\n");
out.write(chars,2,3);
out.write(s);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}