流的概念
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
流的分类
根据处理数据类型的不同分为:字符流和字节流
区别
(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。
根据数据流向不同分为:输入流和输出流
区别
对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
具体又可划分如下:
从图中可看出InputStream和OutputStream,Writer和Reader,分别是字节流,字符流的抽象基类,使用时必须具体实现,
File类
是IO包中唯一代表磁盘文件本身的对象。通过File来创建,删除,重命名文件。File类对象的主要作用就是用来获取文本本身的一些信息。如文本的所在的目录,文件的长度,读写权限等等。
File类具体可实现功能
创建功能
public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了
public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了
public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来
(使用createNewFile()文件创建的时候不加.txt或者其他后缀也是文件,不是文件夹;使用mkdir()创建文件夹的时候,如果起的名字是比如aaa.txt也是文件夹不是文件;)
注意事项:
如果你创建文件或者文件夹忘了写盘符路径,那么,默认在项目路径下。
重命名和删除功能:
public boolean renameTo(File dest):把文件重命名为指定的文件路径
public boolean delete():删除文件或者文件夹
重命名注意事项:
如果路径名相同,就是改名。
如果路径名不同,就是改名并剪切。
删除注意事项:
Java中的删除不走回收站。
要删除一个文件夹,请注意该文件夹内不能包含文件或者文件夹
判断功能
public boolean isDirectory():判断是否是目录
public boolean isFile():判断是否是文件
public boolean exists():判断是否存在
public boolean canRead():判断是否可读
public boolean canWrite():判断是否可写
public boolean isHidden():判断是否隐藏
获取功能
public String getAbsolutePath():获取绝对路径
public String getPath():获取路径
public String getName():获取名称
public long length():获取长度。字节数
public long lastModified():获取最后一次的修改时间,毫秒值
public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
实例化操作:
package edu.xlead;
import org.junit.Test;
import java.io.*;
import java.util.Date;
public class TestIO {
/**
* 测试文件输出流
*/
@Test
public void test1() throws Exception{
FileOutputStream fout=new FileOutputStream("D:\\jjj\\Idea\\流/a.txt");
int a = 20;//00000000 00000000 00000000 00010100
byte[] b = {0,0,0,20};
fout.write(b[0]);
fout.write(b[1]);
fout.write(b[2]);
fout.write(b[3]);
fout.close();//释放流的资源
}
@Test
public void test2() throws Exception{
FileInputStream fin=new FileInputStream("D:\\jjj\\Idea\\流/a.txt");
byte[] b=new byte[4];
b[0]=(byte)fin.read();
b[1]=(byte)fin.read();
b[2]=(byte)fin.read();
b[3]=(byte)fin.read();
System.out.println(b[3]);
fin.close();//释放流的资源
}
@Test
public void test3() throws Exception{
OutputStream fout=new FileOutputStream("D:\\jjj\\Idea\\流/b.txt");
String mesg="Hello World !你好世界!";
byte[] ss=mesg.getBytes();
for (byte s:ss){
fout.write(s);
}
fout.close();
}
@Test
public void test4() throws Exception{
InputStream fin=new FileInputStream("D:\\jjj\\Idea\\流/b.txt");
byte[] b=new byte[fin.available()];//available 从文件头读到末尾-1
int t;
int i=0;
while((t=fin.read())!=-1){
b[i]=(byte)t;
i++;
}
String mesg=new String(b);
System.out.println(mesg);
fin.close();
}
/**
* 对象流 ObjectXXXStream
* @throws Exception
*/
@Test
public void test6() throws Exception{
OutputStream fout=new FileOutputStream("D:\\jjj\\Idea\\流/b.txt");
ObjectOutputStream objout =new ObjectOutputStream(fout);
//objout.write(2);//不往设备里写,写到你new的fout里
objout.writeInt(222);//把整数转换成字节数组存放
objout.writeDouble(23.23);
objout.writeBoolean(true);
objout.writeChar('a');
objout.writeChars("ssdfgyuuuuuuid");
objout.flush();//流写的时候先写在缓存里,只有在对象流关闭或刷新时
objout.close();
fout.close();
}
@Test
public void test7() throws Exception{
InputStream fin=new FileInputStream("D:\\jjj\\Idea\\流/b.txt");
ObjectInputStream objin=new ObjectInputStream(fin);
int tt=objin.readInt();
System.out.println(tt);
double tt1=objin.readDouble();
System.out.println(tt1);
boolean tt2=objin.readBoolean();
System.out.println(tt2);
char tt3=objin.readChar();
System.out.println(tt3);
fin.close();
}
@Test
public void test8() throws Exception{
OutputStream fout=new FileOutputStream("D:\\jjj\\Idea\\流/b.txt");
//转换字节
ObjectOutputStream objout =new ObjectOutputStream(fout);
Date d=new Date();
objout.writeObject(d);
Student s=new Student(2000,"张三");
objout.writeObject(s);
// objout.writeObject(d);
objout.flush();
objout.close();
fout.close();
}
@Test
public void test9() throws Exception{
InputStream fin=new FileInputStream("D:\\jjj\\Idea\\流/b.txt");
ObjectInputStream objin=new ObjectInputStream(fin);
Date d=(Date)objin.readObject();
System.out.println(d);
Student s=(Student)objin.readObject();
System.out.println(s);//对象流要严格按照顺序读写
fin.close();
}
@Test
public void test10() throws Exception{
// //低级流
// OutputStream fout=new FileOutputStream("D:\\jjj\\Idea\\流/b.txt");
// //缓存流
// BufferedOutputStream bout=new BufferedOutputStream(fout);
//加缓存,bout先写到缓存里
// //fout.write(22);//转换成字节写文件里
// bout.write(22);//写到缓存里,性能好
// //bout.flush();//刷新后到文件里
//高级liu
//转换字节
//ObjectInputStream objin=new ObjectInputStream(fin);
ObjectOutputStream objout=new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream("D:\\jjj\\Idea\\流/b.txt")
)
);
Date d=new Date();
objout.writeObject(d);
Student s=new Student(2000,"张三");
objout.writeObject(s);
// objout.writeObject(d);
objout.flush();
objout.close();
}
@Test
public void test11() throws Exception{
//InputStream fin=new FileInputStream("D:\\jjj\\Idea\\流/b.txt");
ObjectInputStream objin=new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("D:\\jjj\\Idea\\流/b.txt")
)
);
Date d=(Date)objin.readObject();
System.out.println(d);
Student s=(Student)objin.readObject();
System.out.println(s);//对象流要严格按照顺序读写
objin.close();
}
}
ackage edu.xlead;
import org.junit.Test;
import java.io.*;
public class TestIO2 {
@Test
public void test1()throws Exception{
//字节流处理字符,处理慢,且一次一个字节 java中一个字符两个字节
//字符流一次两个
FileInputStream fin=new FileInputStream("D:\\jjj\\Idea\\流/a.txt");
int a;
while ((a=fin.read())!=-1){
System.out.println((char) a);
}
fin.close();
}
@Test
public void test2()throws Exception{
//字符流
FileWriter w =new FileWriter("D:\\jjj\\Idea\\流/a.txt");
// w.write('A');
// w.write('中');
w.write("Helllo World !中国中文!");
w.close();
}
@Test
public void test3()throws Exception{
//Reader读一次一个
FileReader fr=new FileReader("D:\\jjj\\Idea\\流/a.txt");
int a;
while ((a=fr.read())!=-1){
System.out.print((char) a);
}
fr.close();
}
@Test
public void test4()throws Exception{
BufferedWriter bw=new BufferedWriter(
new FileWriter("D:\\jjj\\Idea\\流/a.txt")
);
bw.write("Helllo World !中国中文!");
bw.close();
}
@Test
public void test5()throws Exception{
BufferedReader br=new BufferedReader(
new FileReader("D:\\jjj\\Idea\\流/a.txt")
);
String mesg=br.readLine();
System.out.println(mesg);
br.close();
}
@Test
//这个单元测试里没法写
public void test6()throws Exception {
//高级流 把字节流包装成字符流
InputStreamReader ir=new InputStreamReader(System.in);//s.in从键盘读字节
BufferedReader br =new BufferedReader(ir);
String mesg=br.readLine();
System.out.println(mesg);
}
@Test
public void test7()throws Exception {
OutputStreamWriter w=new OutputStreamWriter(System.out);//写到显示器里,命令行显示,标准流一般不要关闭
BufferedWriter bw =new BufferedWriter(w);
bw.write("中国");
bw.flush();
bw.close();
}
@Test
public void test8()throws Exception {
PrintStream ps=new PrintStream("D:\\jjj\\Idea\\流/bb.txt");
ps.println("hello world");
System.out.println();
ps.flush();
ps.close();
}
@Test
public void test9()throws Exception {
PrintWriter pw =new PrintWriter("D:\\jjj\\Idea\\流/bb.txt");
pw.println(20+"你好"+23.23432);
pw.flush();
pw.close();
}
@Test
public void test10()throws Exception {
File f=new File("D:\\sdfsad\\a.txt");
if(f.exists()) {
System.out.println("存在");
}else{
System.out.println("不存在");
f.mkdirs();//创建目录
}
}
@Test
public void test11()throws Exception {
File f=new File("D:\\作业\\a.txt");
if(f.exists()) {
System.out.println("存在");
}else{
System.out.println("不存在");
f.createNewFile();//创建文件
}
}
@Test
public void test12()throws Exception {
File f =new File("D:\\作业\\a.txt");
System.out.println(f.isDirectory());
System.out.println(f.isFile());
}
@Test
public void test13()throws Exception {
File f=new File("D:\\作业");
if(f.isDirectory()){
System.out.println("["+f.getName()+"]");
}else{
System.out.println(f.getName());
}
File [] fs=f.listFiles();
if(fs!=null&&fs.length>0){
listFile(fs,1);
}
}
private void writeBlank(int level){
for(int i=0;i<level;i++){
System.out.print(" ");
}
}
private void listFile(File[] fs,int level){
for(File f:fs){
writeBlank(level);
if(f.isDirectory()){
System.out.println("["+f.getName()+"]");
File[] ff=f.listFiles();
if(ff!=null&&ff.length>0){
listFile(ff,++level);
}
}else{
System.out.println(f.getName());
}
}
}
}
package edu.xlead;
import java.io.Serializable;
public class Student implements Serializable {
private int id;
private String name;
public Student(int id,String name ) {
this.id = id;
this.name=name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
flush和close方法的区别:
flush()方法: 用来刷新缓冲区的,刷新后可以再次写出(字节缓冲流内置缓冲区,如果没有读取出来,可以使用flush()刷新来)
close()方法:用来关闭流释放资源的的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,关闭后不能再写出