IO流:
文件的输入和输出,通过IO完成文件的读写。(以内存作为参照来看)
输入流(InputStream)、读(read):文件输入到内存当中。
输出流(OutputStream)、写(write):内存输出的文件中。
可按照多种方式分类:
1.按照流的方向进行分类,以内存作为参照物。输入流、输出流。
2.按照读取的数据方式不同进行分类,一次读取一个字节byte(字节流),等同于一次读取8个二进制位,这种流是万能的,什么都可以读取。
一次读取一个字符(字符流),这种流为了读取普通文本文件而存在,只能读取纯文本。
注意:所有的流都在java.io.*下。
java IO的四大家族:
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
注意:在java中只要类名以”stream"结尾的都是字节流,以“Reader/Writer“结尾的都是字符流。
所有的流都实现了Closeable接口,都是可关闭的,都有close()方法。流是内存和硬盘的接口,用完之后一定要关闭,不然会耗费很多资源。
所有的输出流都实现了Flushable,都有flush()方法,都是可刷新的。用完输出流后,用flush()方法刷新一下,这个刷新表示将通道中剩余未输出的数据强行输出完,刷新的作用就是清空管道。
注意:如果在输出之后没有用flush,可能会导致丢失数据。
注意:IDEA的当前路径:工程project的根。
节点流:当一个流的构造方法需要一个流的时候,这个被传进来的流被称为节点流。
包装流、处理流:外部负责包装的流。
对于包装流来说,关闭流时只需要关闭最外层流就行,里面的节点流会自动关闭。
例如:
FileReader fis = new FileReader("hello");
BufferedReader br = new BufferedReader(fis);
节点流:fis,包装流:br,关闭流时:br.close();
需掌握的流:
文件:
java.io.FileInputStream
1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
2.字节的方式,完成读的操作,完成输入的操作(从硬盘到内存)
注意:需要try-catch或者throw异常,在finally中关闭资源,关闭流也需要try-catch
方法:
int read() //方法的返回值是读到的字节,读取不到就返回-1.
例子:
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("hello");
int count = 0;
while((count = fis.read())!=-1){
System.out.println(count);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
int read(byte[] b) //一次最多读取b.length()个字节,读取的到字节存到b数组中,返回读到的字节的数量。若b数组已满,则会覆盖数组前面的元素。当没有读到就返回-1.
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("hello");
int count = 0;
byte[] b = new byte[5];
while((count = fis.read(b))!=-1){
System.out.print(new String(b,0,count));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
int available() //返回流当中剩余的没有被读到的字节数量
例如:
byte[] b = new byte[fis.available()];
int count = fis.read(b);
System.out.println(new String(b));
注意:这种方式不适合大文件,因为byte数组不能太大。
long skip(long n) //跳过几个字节不读
java.io.FileOutputStream
文件字节输出流,从内存到硬盘。
原文件是否会被清空,取决于在构造方法的第二个参数,若为true则文件追加写入,若为false则文件清空再写入。
方法:
void write(byte[] b) //把数组b写到对于的硬盘文件中去。
public static void main(String[] args) {
FileOutputStream fos = null;
try {
byte[] b = {58,62,33,54,52};
fos = new FileOutputStream("myhello");
fos.write(b);
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos == null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
void write(byte[] b, int off, int len) //将byte数组的一部分写出
java.io.FileReader
文件字符输入流,只能读取普通文本,读取文本内容时,比较方便,快捷。
read(char[] c)//将文件内容读入字符数组。
java.io.FileWriter
文件字符输出流,只能输出普通文本。
在构造方法的第二个参数,传入true会直接在文件后面继续写入内容,传入false会清空文件再重写。
void write(char[] cbuf) //将一个数组写入文件中
abstract void write(char[] cbuf, int off, int len) //将数组的一部分写入文件中。
void write(String str) //可以直接写入一串字符串。
转换流(将字节流转换为字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
都是在构造方法中传入一个字节流,然后转换为一个字符流。
缓冲流:
java.io.BufferedReader
String readLine() //读入文件的一行,并返回这个字符串。
public static void main(String[] args) throws IOException {
FileReader fis = new FileReader("hello");
BufferedReader br = new BufferedReader(fis);
String s;
while((s=br.readLine())!=null){
System.out.println(s);
}
}
java.io.BufferedWriter
例子:
public static void main(String[] args) throws IOException {
BufferedWriter bf = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("myfile")));
bf.write("hello,i am coming");
bf.write("\n can you hear me");
bf.flush();
bf.close();
}
java.io.BufferedInputStream
java.io.BufferedOutputStream
数据流:
java.io.DataInputStream
java.io.DataOutputStream
这个流可以将数据连同数据类型一并写入文件中,不是普通文本文档,用记事本打不开。
方法:
有writeBoolean(boolean v) 、writeByte(int v) 、writeBytes(String s) 、writeChar(int v)、writeChars(String s) 、writeDouble(double v)、
writeFloat(float v) 、writeInt(int v) 、writeLong(long v) 、writeShort(int v) 等,可以将数据及其类型一并写入文件中。
如果要用DataInputStream去读DataOutputStream的东西,必须要提前知道存储的规则,否则会乱码。
对象流:
transient:游离的,被transient修饰的属性不参与序列化
java.io.ObjectInputStream
常用方法:
Object readObject() //将文件内容反序列化,返回object。
java.io.ObjectOutputStream
常用方法:
void writeObject(Object obj) //将obj对象序列化写入文件中。
注意:传入的obj对象需要实现Serializable接口。
标准输出流:
java.io.PrintWriter
java.io.PrintStream
标准的字节输出流,默认输出到控制台。
不需要手动关闭。
注意:System.setOut(PrintStream ps);给该方法传入一个标准输出流ps,可以将原本print、println打印在控制台中的信息转成写入ps文件中。
例如编写日志文件:
public static void login(String msg){
PrintStream ps = null;
try {
//指向一个日志文件
ps = new PrintStream(new FileOutputStream("log.txt",true));
//改变输出方向
System.setOut(ps);
//日期
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String time = sdf.format(date);
System.out.println(time+":"+msg);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
调用System.out.println时,由于之前System.setOut(ps)修改了内容输出的方向,内容不再输出到控制台了,而是输出到ps指定的文件中。
序列化(Serialize):
Java序列化就是指把Java对象转换为字节序列的过程
反序列化(DeSerialize):
Java反序列化就是指把字节序列恢复为Java对象的过程。
注意:参与序列化和反序列化的对象需要实现Serialize接口
序列化版本号:每个实现了Serialize接口的类都自动生成了一个序列化版本号,用来区别不同的类。
缺陷:修改类中的代码之后,序列化版本号会发生变化。一旦代码确定后,不能再进行修改。
建议给实现Serializable接口的类提供一个固定不变的序列化版本号。
idea工具也可以帮助生成序列化版本号
属性配置文件:当配置文件中的内容类似于 key1=value1,key2=value2的时候,我们把这种文件称为属性配置文件。建议以properties结尾。
java.io.File类
文件或目录的路径名的抽象表示。
File类不能完成文件的读和写
常用方法:
| boolean exists() | //判断当前文件是否存在。 |
| boolean createNewFile() | //当该文件不存在时,以文件形式创建。 |
| boolean mkdir() | //当该文件不存在时,以目录形式创建。 |
| File getParentFile() | //获取父目录 |
| String getParent() | //获取父目录的路径 |
| String getAbsolutePath() | //获取当前文件的绝对路径 |
| String getName() | //获取文件名 |
| boolean isDirectory() | //判断是否是目录 |
| boolean isFile() | //判断是否是文件 |
| long lastModified() | //获取文件上一次修改的时间 |
例如:
public static void main(String[] args) {
File f = new File("hello");
long haomiao = f.lastModified();
Date date = new Date(haomiao);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm-ss SSS");
String s=sdf.format(date);
System.out.println(s);
}
long length() //获得文件大小
File[] listFiles() //返回一个文件数组,里面是当前目录下的所有文件。
1392

被折叠的 条评论
为什么被折叠?



