在学Java时候学到io流的时候感觉好多对象,感觉好乱,我索性就花点功法整理一下,方便大家学习,也方便自己学习!!!
文章目录
字节流
1、File对象
File file = new File("path_name");
这个是对文件操作的函数,而不是对文件内容,它可以判断文件的状态,获取文件的路径,他常用的方法有:
1):file.getPath();
函数返回值为相对路径;
2):file.getAbsolutePath();
函数返回绝对路径;
3):file.canRead();
判断文件是否可读 返回值为boolean,true为可读;
4):file.canWrite();
判断文件是否可写 返回值为boolean,true为可写;
5):file.isFile();
判断是否为一个文件 返回值为boolean,true 是一个文件;
6):file.isDirectory;
判断是否为一个目录 返回值为boolean,true 是一个目录;
7):file.lastModified();
返回值为long,为最后一次的修改时间;(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format((new Date(file.lastModified())))
可格式化时间;)
8):file.listFiles();
返回当前目录下所有的文件,返回值File[];
9):file.exists();
判断当前文件或目录是否存在 返回值为boolean,true为存在当前路径,false,不存在当前路径;
10):file.createNewFile();
只能用于创建文件,返回值为boolean,true创建成功;
11):file.mkdir();
只能用于创建目录,并且只能创建一级目录;
12):file.mkdirs();
只能用于创建目录,可以创建多级目录;
13):file.list();
列出目录下的文件,返回值为String[];
14):file.length()
返回文件的大小,如果是目录或者没有返回0;
15):file.delete();
删除文件或目录,返回值为boolean,true为删除成功;
16):file.deleteOnExit();
在虚拟机运行结束时删除文件;
17):file.renameTo(new File("path"))
重命名此文件到path;
举一个小例子,遍历并列出某一文件夹下面的所有子文件:
public class api {
public static void main(String[] args) throws IOException {
api Data = new api();
Data.ListFile(new File("D:"+File.separatorChar+"eclipseWorkSpace"+File.separatorChar+"test"),0);
}
public void ListFile(File file,int level) {
for(int i=0;i<level;i++) {
System.out.print(" ");
}
if(level!=0)
System.out.print("└──");
System.out.println(file.getName());
if(file.isDirectory()) {
File[] files = file.listFiles();
for (File f : files) {
ListFile(f,level+1);
}
}
}
}
输出:
test
└──.classpath
└──.project
└──.settings
└──org.eclipse.core.resources.prefs
└──org.eclipse.jdt.core.prefs
└──222.txt
└──bin
└──cn
└──yun
└──api.class
└──src
└──cn
└──yun
└──api.java
└──strawberry.jpg
2、FileInputStream 对象
FileInputStream fin = new FileInputStream(new File("path") );
从系统中的文件读取,有两个常用重载函数FileInputStream(File);
和FileInputStream(String);
这个对象是和文件打交道的对象,他有以下常用的方法:
1):fin.read();
从这个流读取下一个字节的数据,返回值为-1则为读到文件末尾,所以可以通过以下方式去读取整个文件
int temp;
while((temp=fin.read())!=-1){
System.out.print(char(temp));
}
2):fin.read(byte[] b);
读取一定长度的字节,存入到b,返回值为读入字节的数量,-1为读取到文件末尾,可以通过一下方式读取文件
byte[] bs = new byte[1024];
int temp;
while((temp=fin.read(bs))!=-1){
System.out.print(new String(bs,0,temp));
}
3):fin.close();
关闭当前文件流,每次操作完都需要关闭流,无返回值。
3、FileOutputStream对象
FileOutputStream fout = new FileOutputStream(new File("path") );
是和FileInputStream 配合着用的,将读取的内容写入到文件,也是和文件打交道,有两个常用的重载函数
1):FileOutputStream(String name);
接受字符串,虽然结束字符串但是在内部已经给你new File()了;
2):FileOutputStream(String name, boolean append)
接受一个字符串和一个布尔值,字符串和上面一样,布尔值为true则为追加写入,也就是不覆盖原文,false为覆盖写入,会覆盖全文;
3):FileOutputStream(File file)
接受一个File对象和1)一样;
4):FileOutputStream(File file, boolean append)
接受一个File对象和2)一样;
他的常用方法如下:
1): fout.write(int b);
接受一个int值,会把此int值当作ascii处理,转换陈对应的文字,例如:
int temp;
while((temp=fin.read())!=-1){
fout.write(temp);
}
2):fout.write(byte b[])
接收一个byte数组,将整个byte数组进行处理,和一个read(byte b[])配合使用,例如
byte[] bs = new byte[1024];
int temp;
while((temp=fin.read(bs))!=-1){
fout.write(bs);
}
3):fout.write(byte b[], int off, int len)
,参数解释:byte[],读到的byte[]数组,
off,需要存放byte[]内容的起始位置,
len,byte[]数组的结束位置。例如
byte[] bs = new byte[1024];
int temp;
while((temp=fin.read(bs))!=-1){
fout.write(bs,0,temp);
}
这样写就不会像上面那样写入很多没有用数据。
4):fout.close()
,关闭此流,任何时候都要记住的操作。
4、ByteArrayOutputStream对象
ByteArrayOutputStream bsout = new ByteArrayOutputStream();
该对象是将一个bs数组写入到内存,是和内存打交道的对象:常用的方法如下:
1):bsout.write(temp);
将一个int值写入到内存中;
2):bsout.write(byte[] bs,int off,int len);
将off~len长度的bs写入到内存;
3):byte[] bs = bsout.toByteArray()
创建一个新分配的字节数组。它的大小是这个输出流的当前大小,缓冲区的有效内容已复制到其中;
4):bsout.size()
返回缓冲区的当前大小;
5):bsout.toString(String charset)
charset为制定的字符集,此方法可以将内存的二进制数据准换成字符串
5、ByteArrayInputStream对象
ByteArrayInputStream bin = new ByteArrayInputStream(byte[] bs)
;该对象和ByteArrayOutputStream 配合使用,作用也恰恰相反,自身的方法和FileInputStream 也非常相似,次函数是从内存想程序内读取一段byte数组,也是和内存打交道的对象,常用方法如下:
1):int temp = bin.read();
从这个流读取下一个字节数据,当读取到末尾是返回值为-1;
2):bin.read(byte[] bs)
,分块读取,读取bs数组这么大的字节流放到bs数组里,当读取到末尾是返回值为-1;
6、BufferedInputStream 字节缓冲输入流和 BufferedOutputStream 字节缓冲输出流
BufferedInputStream和BufferedOutputStream 为另一个输入流添加了功能,即缓冲输入并支持标记和重置方法的功能。 创建BufferedInputStream时,将创建一个内部缓冲区数组。 当读取或跳过流中的字节时,根据需要从包含的输入流中重新填充内部缓冲区,一次填充许多字节。BufferedOutputStream 该类实现缓冲的输出流。 通过设置这样的输出流,应用程序可以将字节写入底层输出流,而不必为写入的每个字节引起对底层系统的调用。这样就会大大提升普通InputStream是的时间速率,他的使用方法和FileInputStream是一样的,接下来为举个例子:
第一个未使用修饰器
public static void main(String[] args) throws IOException {
long t1 = System.currentTimeMillis();
FileInputStream in = new FileInputStream(new File("1.mp4"));
FileOutputStream out = new FileOutputStream(new File("temp.mp4"));
byte[] buf = new byte[1024];
int temp;
while ((temp=in.read(buf))!=-1) {
out.write(buf, 0, temp);
}
long t2 = System.currentTimeMillis();
System.out.println("运行时间为: "+(t2-t1));
in.close();
out.close();
}
运行时间为: 27
第二个使用装饰器
public static void main(String[] args) throws IOException {
long t1 = System.currentTimeMillis();
FileInputStream in = new FileInputStream(new File("1.mp4"));
BufferedInputStream bin = new BufferedInputStream(in);//经过BufferedInputStream 装饰
FileOutputStream out = new FileOutputStream(new File("temp.mp4"));
BufferedOutputStream bout = new BufferedOutputStream(out);//经过BufferedOutputStream 装饰
byte[] buf = new byte[1024];
int temp;
while ((temp=bin.read(buf))!=-1) {
bout.write(buf, 0, temp);
}
long t2 = System.currentTimeMillis();
System.out.println("运行时间为: "+(t2-t1));
bout.flush();
bin.close();
bout.close();
运行时间为: 7//运行时间大大减小
7、DataOutputStream 数据输出流
此对象是和DataInputStream一起配合使用的,数据输出流允许应用程序以可移植的方式将原始Java数据类型写入输出流。 然后,应用程序可以使用数据输入流来读回数据。此对象可以直接写入一个java的数据类型,常用方法为
1):dout.write(此处拼接java的数据类型)
;将一个java数据类型的值写出去。
8、DataInputStream 数据输入流
此对象要从DataOutputStream 读入数据,并且读入的顺序要和写入的顺序要一致,否则将会报异常,常用的方法有:
1):din.read(此处拼接java的数据类型)
;将一个java数据类型的值读入。
结合 DataOutputStream
和 DataInputStream
做一个小例子
public class api {
public static void main(String[] args) throws IOException {
api Data = new api();
Data.InputData(new File("222.txt"));
Data.ReadData(new File("222.txt"));
}
public void InputData(File file) throws IOException {
DataOutputStream dout = new DataOutputStream(new FileOutputStream(file));
dout.writeInt(15);
dout.writeUTF("hello");
dout.close();
}
public void ReadData(File file) throws IOException {
DataInputStream din = new DataInputStream(new FileInputStream("222.txt"));
int ReadData = din.readInt();
String ReadString = din.readUTF();
System.out.println("读到的数据 :"+ReadData+"\n读到的字符串 :"+ReadString);
din.close();
}
}
读到的数据 :15
读到的字符串 :hello
9、ObjectOutputStream 对象输出流 和 ObjectInputStream 对象输入流
ObjectOutputStream 对象的序列化流,是和ObjectInputStream配合使用,作用:把对象转成字节数据的输出到文件中保存,对象的输出过程称为序列化,可实现对象的持久存储。
一个对象要想序列化,必须满足两个条件
① 该类必须实现 java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出 NotSerializableException 。
每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。
② 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰
public class api {
public static void main(String[] args) throws IOException, ClassNotFoundException {
api Data = new api();
Data.InputData(new File("222.txt"));
Data.ReadData(new File("222.txt"));
}
public void InputData(File file) throws IOException {
ObjectOutputStream dout = new ObjectOutputStream(new FileOutputStream(file));
dout.writeObject(new Person("小明", 23));
dout.close(); //里面实现了 flush();不用在 调用flush;
}
public void ReadData(File file) throws IOException, ClassNotFoundException {
ObjectInputStream din = new ObjectInputStream(new FileInputStream("222.txt"));
Person person = (Person) din.readObject();
System.out.println("读到的数据 :"+person.getName()+"今年:"+person.getAge());
din.close();
}
}
class Person implements Serializable{ //必须实现Serializable这个接口才能序列化
private String name;
private int age;
public Person(String name,int age) {
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
以上是常用的java.IO的字节流对象的总结,还有一些不常用的先不总结了,接下来我会总结ava.IO的字符流对象。有不详细的地方可以一起讨论学习。