Java IO流
IO 流
1. 流
1.1 流的概念:
内存与存储设备之间传输数据的通道
1.2 流的分类
按方向分
- 输入流: 将 < 存储设备 > 中的内容读入到 < 内存 > 中.
- 输出流: 将 < 内存 > 中的内容写入到 < 存储设备 > 中.
按代为分
- 字节流: 以字节为单位, 可以读写所有数据.
- 字符流: 以字符为单位, 只能读写文本数据.
按功能分
- 节点流: 具有实际传输数据的读写功能.
- 过滤流: 在街电流的基础之上增强功能.
2. 字节流
2.1 字节流的父类(抽象类)
InputStream 字节输入流
- public int read() {}
- public int read(byte[] b) {}
读取输入流存储在 字节数组b中
- public int read(byte[] b, int off , int len){}
偏移量off, 读取长度len
OutputStream 字节输出流
- public void write (int n) {}
- public void write (byte[] b) {}
- public void write (byte[] b, int off, int len) {}
上面抽象类的两个子类:
2.2-1 FileInputStream
- public int read (byte[] b)
从流中读取多个字节, 将读到的内容存入b数组, 返回实际读到的字节数; 如果达到文件的尾部, 则返回-1
2.2-2 FileOutputStream
- public void write (byte[] b)
一次写多个字节, 将b数组中所有的字节, 写入输出流
package cn.ylq.filestream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileIOStudy {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("F:\\文档\\杂七杂八\\test.txt");
byte[] dataList = new byte[1024];
int count = fis.read(dataList);
System.out.println(count);
System.out.println(new String(dataList));
fis.close();
FileOutputStream fos = new FileOutputStream("F:\\文档\\杂七杂八\\test.txt",true);
String line = "\n 因为有了因为,\n 所以有了所以,\n 既然已成既然,\n 何必再说何必.";
fos.write(line.getBytes());
fos.close();
}
}
案例-复制一张图片
package cn.ylq.filestream;
import java.io.*;
public class Demo01 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("F:\\文档\\杂七杂八\\test\\pic.jpg");
FileOutputStream out = new FileOutputStream("F:\\文档\\杂七杂八\\test\\pic2.jpg",true);
byte[] buf = new byte[1024*8];
int counter = 0;
while((counter=in.read(buf))!=-1){
out.write(buf,0,counter);
}
in.close();
out.close();
System.out.println("复制完成");
}
}
2.3 字节缓冲流
- 缓冲流: BufferedInputStream / BufferedOutputStream
- 提高IO销量, 减少访问磁盘的次数;
- 数据存储在缓冲区中, flush 是将缓存区的内容写入文件中, 也可以直接 close .
package cn.ylq.filestream;
import java.io.*;
public class Demo02 {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream( "F:\\文档\\杂七杂八\\test.txt" );
BufferedInputStream bis = new BufferedInputStream(fis,1024*8);
int data = 0;
while((data=bis.read())!=-1){
System.out.print((char)data);
}
bis.close();
}
}
package cn.ylq.filestream;
import java.io.*;
public class Demo03 {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("F:\\文档\\杂七杂八\\试试中文行不行.txt");
BufferedOutputStream bos=new BufferedOutputStream(fos);
String line = "你好,乱码";
byte[] cells = line.getBytes();
bos.write(cells);
bos.flush();
bos.close();
}
}
2.4 对象流
- 对象流: ObjectOutputStream / ObjectInputStream
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串功能
- 增强了读写对象的功能
readObject() 从流中读取一个对象
writeObject(Object obj) 向流中写入一个对象
序列化的对象必须实现Serializable接口,其对象属性也必须实现Serializable接口
类里声明赋值属性serialVersionUID 序列化版本ID,保证反序列化回来的也是同一个类
transient关键词可以让其后的属性方法不被序列化, 短暂的, 意味保存在内存中
静态属性也不能呗序列化
-
读写的对象也可以是List实现批量操作
-
使用流传输对象的过程称为序列化\反序列化
package cn.ylq.filestream;
import java.io.Serializable;
public class Ox implements Serializable {
private int id;
private String name;
//后面不用看
public Ox() {
}
public Ox(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Ox{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
package cn.ylq.filestream;
import java.io.*;
public class Demo04 {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("F:\\文档\\杂七杂八\\Ox");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Ox no1 = new Ox(1,"小花");
Ox no2 = new Ox(2,"宫本武藏");
oos.writeObject(no1);
System.out.println(no1+"导入完成!");
oos.writeObject(no2);
System.out.println(no2+"导入完成!");
oos.close();
}
}
package cn.ylq.filestream;
import java.io.*;
public class Demo05 {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("F:\\文档\\杂七杂八\\Ox");
ObjectInputStream ois = new ObjectInputStream(fis);
Object my;
Object yours;
my=ois.readObject();
System.out.println(my);
yours=ois.readObject();
System.out.println(yours);
ois.close();
}
}
3. 字符流
3.1 字符流的的父类(抽象类)
Reader 字符输入流
- public int read ( ){}
- public int read (char[] c) {}
- public int read (char[] b, int off, int len) {}
Writer 字符输出流
- public void write (int n) {}
- public void write (String str) {}
- public void write (char[] c) {}
3.2 文件读写
FileReader
- public int read (char[] c)
从流中读取多个字符, 将读到的内容存入c数组, 返回实际读到的字符数; 如果达到文件的尾部, 则返回-1
Object - Reader - InputStreamReader - FileReader
read方法假定默认字符编码和缓冲区大小适合当的.如果要自己指定这些值,
可以现在FileInputStreamReader上构造一个InputStreamReader
public class Demo06 {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("F:\\文档\\杂七杂八\\试试中文行不行.txt");
/* int data = 0;
while((data=fr.read())!=-1){
System.out.print((char)data);
}*/
int count = 0;
char[] buf =new char[1024];
while((count=fr.read())!=-1) {
String line = new String(buf);
System.out.println(line);
}
fr.close();
}
}
FileWriter
- public void write (String str)
一次写多个字符, 将字符串中所有的字符, 写入输出流
package cn.ylq.filestream;
import java.io.*;
public class demo07 {
public static void main(String[] args) throws Exception {
FileWriter fw = new FileWriter("试试中文行不行.txt");
fw.write("/r/n人的梦想是不会终结的!");
fw.flush();
fw.close();
}
}
3.3 字符缓冲流
- 缓冲流: BufferedReader / BufferedWriter
- 高效读写
- 支持输入换行符
- 可一次写(读)一行
- BufferedReader 的 readLine() 方法, 读取一行字符串.
- BufferedWriter 的 newLine() 方法, 输入一个换行符. 比起手动录入 \r\n 可以适配不同操作系统的换行
package cn.ylq.filestream;
import java.io.*;
public class Demo09 {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader ("F:\\文档\\杂七杂八\\test.txt");
BufferedReader br = new BufferedReader(fr);
String line = "这是个空文件呀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
while(line!=null) {
line = br.readLine();
System.out.println(line);
}
br.close();
}
}
4. 打印流 PrintWriter
print 方法比起 write 可以跟的参数类型更多
package cn.ylq.filestream;
import java.io.*;
public class Demo11 {
public static void main(String[] args) throws Exception {
PrintWriter pw = new PrintWriter("F:\\文档\\杂七杂八\\暹罗猫.txt");
pw.println(97);
pw.println(3.1415927);
pw.println(true);
pw.println("嬲");
pw.close();
}
}
5. 转换流
- 桥转换流: InnputStreamReader / OutputStreamWriter
- 可将字节流转换为字符流
- 可设置字符的编码方式
package cn.ylq.filestream;
import java.io.*;
public class Demo13 {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("F:\\文档\\杂七杂八\\字节码文件哦");
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
osw.write("长颈鹿的脖子那么长 哽咽的时候是不是很难受\r\n" +
"章鱼有三颗心脏 心痛的时候是不是很疼\r\n" +
"乌鸦可以学人说话 尴尬的时候会不会装咳嗽\r\n" +
"骆驼有长长的睫毛 想哭的时候能不能说眼睛进了沙\r\n" +
"蛇没有宽宽的肩膀 她累的时候给不了能够依靠的温暖\r\n" +
"小强有两个大脑 孤单的时候会不会一起想着谁\r\n" +
"我没有长长的脖子 却哽咽的说不出话\r\n" +
"我没有三颗心脏 体会不到无法忍受的痛再多三倍\r\n" +
"我假装咳嗽 假装被沙子迷了眼 你也没有看我一眼\r\n" +
"是因为我太弱小 没有很可靠的肩膀么\r\n" +
"无时无刻的清澈的想念 一定比两个大脑一起想你还多吧\r\n" +
"蜉蝣只能活很短 可能一辈子都来不及和心里珍藏的那个人说一些想说的话\r\n" +
"我又能活多久 时间会不会给我可以开口的勇气\r\n" +
"把人生看做是自己独一无二的创作 便不会频频回首\r\n" +
"你会不会忽然地出现 在旧时光的风景里 成为珍藏一生的美丽");
osw.close();
}
}
package cn.ylq.filestream;
import java.io.*;
public class Demo12 {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream ("F:\\文档\\杂七杂八\\字节码文件哦");
InputStreamReader isr = new InputStreamReader(fis,"utf-8");
int data = 0;
while ((data = isr.read())!=-1){
System.out.print((char) data);
}
isr.close();
}
}
File类
- 概念: 代表物理盘符中的一个文件或文件夹.
- 方法:
- createNewFile()
创建一个新文件- mkdir()
创建一个新目录- delete()
删除文件或空目录- exists()
判断File对象所代表的对象是否存在- getAbsolutePath()
获取文件的绝对路径- getName()
取得名字- getParent()
获取文件目录所在的目录- isDirectory()
是否是目录- isFile()
是否是文件- length()
获取文件的长度- listFiles()
列出目录中的所有内容- rename()
修改文件名为
package cn.ylq.filestream;
import java.io.File;
public class Demo14 {
public static void main(String[] args) {
separator();
}
public static void separator() {
System.out.println("路径分隔符: [ " + File.pathSeparator + " ]");
System.out.println("文件分隔符: [ " + File.separator + " ]");
}
}
结果: (参考环境变量参数值理解)
路径分隔符: [ ; ] 路径1和路径2之间
文件分隔符: [ \ ] 路径1内各级目录之间
package cn.ylq.filestream;
import java.io.File;
import java.util.Date;
public class Demo14 {
public static void main(String[] args) throws Exception {
fileOperate();
}
public static void fileOperate() throws Exception {
File f = new File("F:\\文档\\杂七杂八\\维京战机");
//创建文件
if(!f.exists()){
boolean b1 = f.createNewFile();
System.out.println("文件创建:"+b1);
}
//获取文件的绝对路径
System.out.println("文件的绝对路径:"+f.getAbsolutePath());
//获取文件的路径 (和创建时候写的一样)
System.out.println("文件的路径:"+f.getPath());
//获取文件名称
System.out.println("文件的名称:"+f.getName());
//获取父目录
System.out.println("文件父目录:"+f.getParent());
//获取文件的长度
System.out.println("文件长度:"+f.length());
System.out.println("文件最后的修改时间:"+new Date(f.lastModified()));
//判断文件时候可写 注意可读和可执行在linux才可以用
System.out.println("文件是否可写:"+f.canWrite());
//判断是否是文件
System.out.println("是否是文件:"+f.isFile());
//判断是否隐藏
System.out.println("是否隐藏:"+f.isHidden());
//删除文件
boolean b2 = f.delete();
System.out.println("文件删除:"+b2);
//另一种JVM删除, 记得删掉上面的删除代码
f.deleteOnExit();
Thread.sleep(5000);
}
}
package cn.ylq.filestream;
import java.io.File;
public class Demo15 {
public static void main(String[] args) throws InterruptedException {
dicOperation();
}
public static void dicOperation() throws InterruptedException {
File dir = new File("F:/我试试正斜杠\\我再试试反斜杠");
//比起mkdir方法, mkdirs方法可以创建多级目录
if (!dir.exists()) {
dir.mkdirs();
}
//只会删除最后一目录, 只有空目录可以删除
dir.delete();
//用JVM删除
dir.deleteOnExit();
Thread.sleep(5000);
//获取绝对路径 路径 名称 父目录 最后一次修改时间 啥的和 文件的一样
//判断是否是文件夹 判断是否隐藏也一样
//遍历文件夹 注意用list方法返回的是字符串数组,用listFiles返回的是File数组
File dir2 = new File ("F:\\文档\\杂七杂八");
String[] files = dir2.list();
for(String file:files){
System.out.println(file);
}
}
}
FileFileter接口
- public interface FileFilter
- boolean accept (File pathname)
-当调用File类中的ListFiles()方法时, 支持传入FileFilter接口接口实现类, 对获取文件进行过滤, 只有满足条件的文件才可出现在listFiles()的返回值中
package cn.ylq.filestream;
import java.io.File;
import java.io.FileFilter;
public class Demo16 {
public static void main(String[] args) {
File dir = new File ("F:\\文档\\杂七杂八");
FileFilter filter = new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".txt")){
return true;
}
else {
return false;
}
}
};
File[] files = dir.listFiles(filter);
for (File file:files){
System.out.println(file);
}
}
}
递归调用遍历文件夹
package cn.ylq.filestream;
import java.io.File;
//递归调用遍历文件夹
public class Demo17 {
public static void main(String[] args) {
File f = new File("F:\\文档\\杂七杂八");
printDir(f);
}
public static void printDir(File thisDir) {
File[] files = thisDir.listFiles();
if(files!=null&&files.length>0){
for(File file:files){
if(file.isFile()){
System.out.println(file.getAbsolutePath());
}
else{
printDir(file);
}
}
}
}
}
递归删除略
Propertises
- Properties: 属性集合
- 特点
- 存储属性名和属性值
- 属性名和属性值都是字符串类型
- 没有泛型
- 和流有关