java IO学习
流的概念
是内存和存储设备之间传输数据的一个通道
流的分类
-
按照单位:
-
字节流,可以输入任何数据,因为任何数据在内存中都是以字节的方式存储的
-
字符流,只能读取文本形式的数据,因为有的字符是一个字节、两个字节、三个字节
-
-
按照功能:
- 节点流,也叫底层流,具有实际传输数据的读写功能
- 缓冲流,在节点流只上实现的增强功能
字节流的学习
字节流输入的父类(抽象类):分别是InputStream和OutputStream
//用这两个抽象类的用来读文件的子类【FileInputStream,FileOutputStream】来读取文件和写入文件
//实现文件的复制
public class FileCopy {
public static void main(String[] args) throws Exception {
FileInputStream in = new FileInputStream("d:\\1.png");
FileOutputStream out = new FileOutputStream("d:\\2.png");
byte[] buffer = new byte[1024]; //此处的byte不能是Byte
int count=0;
while((count=in.read(buffer))!=-1){
out.write(buffer,0,count); //count输出的是读出字节的个数
}
in.close(); //用完之后记得关闭流
out.close();
}
}
缓冲流学习
- 缓冲流BufferedInputStream 和BufferedOutputStream实际上就是在类的内部加了一个8K的缓冲区,每次读写都会先放到缓冲区里面,提高了IO效率
//用BufferedInputStream实现文件读入
public class MyBufferdInput {
public static void main(String[] args) throws Exception {
//注意此处需要放入一个底层的 InputStream对象
BufferedInputStream bin = new BufferedInputStream(new FileInputStream("d:\\hello.txt"));
int data=0;
while((data=bin.read())!=-1){
System.out.print((char)data);
}
bin.close();
}
}
//用BufferedOutputStream实现文件写出
public class MyBufferdInput {
public static void main(String[] args) throws Exception {
//注意此处需要放入一个底层的 OutputStream对象【节点流】
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream("d:\\helloout.txt"));
int data=0;
String s = "hello";
for (int i = 0; i < 10; i++) {
bout.write(s.getBytes());
bout.flush(); //这句代码的意思是,没写出到缓冲区一次就将内容写到磁盘,不等到写满8k
}
bout.close(); //如果上面没有刷新在这也会全部写出到磁盘
}
}
对象流
- 使用流 写入/读出 对象 就叫 序列化/反序列化
- 注意事项:
- 序列化的类必须实现Serializable接口
- 序列化类中的对象属性也需要实现Serializable接口
- 静态属性不能被序列化
- 如果类中的属性加上transient(瞬时的)之后,也不能被序列化
- 如果想要多个对象同时序列化,可以用集合 比如list来序列化
public class Serialize {
public static void main(String[] args) throws Exception{
//序列化,注意此处需要底层流对象
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("d:\\stu.txt"));
Student stu1 = new Student("张三", 18);
Student stu2 = new Student("李四", 22);
//out.writeObject(stu);
List<Student> list = new ArrayList<>();
list.add(stu1);
list.add(stu2);
out.writeObject(list); //序列化一个链表
out.close();
System.out.println("序列化成功");
//反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("d://stu.txt"));
//Object returnstu=in.readObject();
ArrayList<Student> returnStu= (ArrayList<Student>) in.readObject();
in.close();
System.out.println(returnStu.toString());
}
}
class Student implements Serializable {
private String name;
private int age;
public static int id; //这两个属性不能序列化
public transient char sex;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//输出
序列化成功
[Student{name='张三', age=18}, Student{name='李四', age=22}]
字符流
- 常见字符编码:utf-8,gbk
- 因为字节流读汉字会存在问题,所以有了Reader和Writer(父类,抽象类)
//FileReader和FileWriter的使用:其实和上面的FileInputStream和FileOutputStream用法是一样的
public class FileReaderAndFileWriter {
public static void main(String[] args) throws Exception{
//将汉字写入文件
FileWriter fw = new FileWriter("d://filewrite.txt");
for (int i = 0; i < 5; i++) {
fw.write("你好世界\r\n");
}
fw.close();
FileReader fr = new FileReader("d://filewrite.txt");
int data=0;
while ((data = fr.read()) != -1) {
System.out.print((char)data);
}
}
}
字符缓冲流
- 可以读取一行
//BufferReader和BufferWriter的使用:和上面的字节缓冲流基本上没有区别
public class BufferedReaderAndBufferedWriter {
public static void main(String[] args) throws Exception {
BufferedWriter bw = new BufferedWriter(new FileWriter("d://bw.txt"));
for (int i = 0; i < 5; i++) {
bw.write("好好学习,天天向上");
bw.newLine(); //功能就是\r\n(换行)
}
bw.close(); //关闭流
System.out.println("写入成功");
BufferedReader br = new BufferedReader(new FileReader("d://bw.txt"));
String ans=null;
while((ans=br.readLine())!=null){ //可以一行一行的读取
System.out.println(ans);
}
br.close(); //关闭流
}
}
转换流
- 硬盘中的字节和内存中的字符的转换,和上面的区别是,读和写的时候可以指定编码方式
//OutputStreamWriter和InputStreamReader的使用
public class InputStreamWriter {
public static void main(String[] args) throws Exception{
//将文件以 utf-8 的格式写入到文件
OutputStreamWriter osw = new OutputStreamWriter(//注意此处也需要底层流
new FileOutputStream("d://osw.txt"), "utf-8");
for (int i = 0; i < 5; i++) {
osw.write("你好,世界\r\n");
}
osw.close();
System.out.println("输出成功");
//将文件读出也必须以 utf-8 的方式读出 gbk--对应的是ANSI
InputStreamReader isr = new InputStreamReader(
new FileInputStream("d://osw.txt"),"utf-8" //注意此处如果用gbk读出来的
//就是乱码
);
int data=0;
while ((data = isr.read()) != -1) {
System.out.print((char)data);
}
}
}
文件、文件夹的操作
基本操作
public class MyFile {
public static void main(String[] args) throws Exception {
//分隔符
System.out.println(File.pathSeparator); //路径分隔符;
System.out.println(File.separator); //名称分隔符\
File file = new File("d://a.txt");
//创建文件
if (!file.exists()){
file.createNewFile();
}
//删除文件
/*file.delete();*/
//获取文件信息
System.out.println(file.getName()); //文件名
System.out.println(file.length()); //文件所占的字节数
System.out.println(file.getPath()); //文件的路径
System.out.println(file.isFile()); //是否是文件
System.out.println(file.canWrite()); //文件是否可写
}
}
//文件夹的操作
//和上面有区别的就是创建文件夹、可以遍历文件夹【用list】
file.makedir //创建单级目录
fiel.makedirs //创建多级目录
文件过滤
//过滤出文件夹中后缀名为.png的文件
public class FIleFilter {
public static void main(String[] args) {
File dir = new File("d:files");
File[] files=dir.listFiles(new FileFilter() { //用匿名内部类的方式实现FileFilter接口
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".png")) { //过滤出后缀名为.png的文件
return true;
} else {
return false;
}
}
});
for (File file:files) {
System.out.println(file.getPath());
}
}
}
文件遍历
//递归遍历文件夹
public class FilePrint {
public static void main(String[] args) {
printDir(new File("d://files"));
}
public static void printDir(File dir) {
File[] files = dir.listFiles(); //只要遍历就需要用到集合
for (File file:files) {
if (file.isFile()) {
System.out.println(file.getPath()); //简单递归
} else {
printDir(file);
}
}
}
}
和流有关的集合properties的使用
public class Propertirs {
public static void main(String[] args) throws Exception{
Properties pro = new Properties();
pro.setProperty("张三", "18"); //注意:properties里面放的key,value都是String类型的
pro.setProperty("李四", "北京");
Set<String> pros=pro.stringPropertyNames();
for (String s:pros) {
System.out.println(s+pro.getProperty(s));
}
//通过流输出集合到文件
/*PrintWriter out=new PrintWriter("d://pro.properties");
pro.list(out);
out.close();*/
//通过store来向流中输出
OutputStream out = new FileOutputStream("d://properties");
pro.store(out,"what");
out.close();
//通过load来读出流
Properties pro2 = new Properties();
FileInputStream in = new FileInputStream("d://properties");
pro2.load(in);
in.close();
System.out.println(pro2.toString());
}
}