1.流的概念
概念:内存与存储设备之间传输数据的通道
以内存为参照,存储设备往内存中输入数据就是输入流、内存往存储设备中输出数据就是输入流
按照单位分类就分为字节流和字符流
字节流:以字节为单位、可以读写所有数据
字符流:以字符为单位、只能读写文本数据
按照功能来划分的话可以分为节点流和过滤流
节点流:具有实际传输数据的读写功能
过滤流:在节点流的基础之上增强功能
字节流
输入流、子类一:FileInputStream
package IO;
import java.io.FileInputStream;
/*文件字节输入流
*
* */
public class Demo01FileInputStream {
public static void main(String[] args) throws Exception{
//创建字节流
FileInputStream fileInputStream = new FileInputStream("d:\\aaa.txt");
/*while ((fileInputStream.read())!=-1){ //因为程序到了最后读取不到内容的时候会给出一个结果-1
//如果直接输出的话就会得到ascall编码,需要转换类型输出才可以,并且直接输出(fileInputStream.read()会得到间隔一位的字符
System.out.print((char) (fileInputStream.read()));
}*/
//一次读取一个字节
/* int a=0;
while ((a=fileInputStream.read())!=-1){ //因为程序到了最后读取不到内容的时候会给出一个结果-1
System.out.print((char)a);//如果直接输出的话就会得到ascall编码,需要转换类型输出才可以,这样子相比较前面的会得到完整内容
}*/
//一次读取多个字节(多个字节需要创建byte数组)
byte[] buf=new byte[1048];
int count=0;
while ((count=fileInputStream.read(buf))!=-1){
System.out.println(new String(buf, 0, count));
}
fileInputStream.close();//需要及时关闭,不然会浪费内存
}
}
输入流、子类二:FileOutputStream
package IO;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
/*子类二:FileOutputStream
输入默认的是输入的Ascall码值,如果要写入字符串就需要先设定一个字符串在用getBytes方法写入字符串才可以
* */
public class Demo02FileOutputStream {
public static void main(String[] args) throws Exception{
//创建之前要记得抛出异常\当写出true的时候再次写入就只需要再次运行就可以*
FileOutputStream o=new FileOutputStream("d:\\bbb.txt",true);
//
o.write(10);//写入10会输出10的Ascall码值
o.write('a');
o.write('b');
//字符串写入*
String a="helloworld";
o.write(a.getBytes(StandardCharsets.UTF_8));
o.close();
}
}
2.字节流复制文件
package IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*文件字节流的复制
复制的可以是图片也可以是文字
*
* */
public class Demo03Copy {
public static void main(String[] args) throws IOException {//抛出异常需要选用Exception,不然后面的read方法会报错
FileInputStream fileInputStream = new FileInputStream("c:\\ccc.jpg");
FileOutputStream fileOutputStream = new FileOutputStream("c:\\ccc1.jpg");
//一边读一边写入
byte[] a=new byte[1024*4]; //1024就是1k,4倍就是4k
int count=0; //count就是实际读取的字节个数
while ((count=fileInputStream.read(a))!=-1){
fileOutputStream.write(a,0,count); //按照a的规格来写入,字节流个数是count为个数
}
//关闭
fileInputStream.close();
fileOutputStream.close();
}
}
字节缓冲流
提高IO效率,减少访问磁盘的次数
当close的时候缓冲区会自动刷新一次
数据存储在缓冲区,flash是将缓存区的内容写入文件中,也可以直接close
好处:将全部的数据先都保存在缓冲区中,最后一次调用,从而占用最少的资源。
字节缓冲输入流BufferedInputStream
package IO;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
/*字节缓冲流
* */
public class Demo04BufferedInputStream {
public static void main(String[] args) throws Exception{
FileInputStream fileInputStream = new FileInputStream("d:\\aaa.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//读取
int data;
while ((data=bufferedInputStream.read())!=-1){
System.out.print((char)data);
}
/*while ((bufferedInputStream.read())!=-1){
System.out.println(bufferedInputStream.read());
}
如果这样子直接输出的话会输出Ascall码的值*/
//自己创建缓冲区
/* int count=0;
byte[] a=new byte[1024];
while ((count=bufferedInputStream.read(a))!=-1){
System.out.println(new String(a,0,count));
}*/
//关闭
bufferedInputStream.close();//关闭这个相当于同时关闭fileInputStream
}
}
字节缓冲输出流BufferedOutputStream
package IO;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
public class DEMO05BufferedOutputStream {
public static void main(String[] args) throws Exception{
FileOutputStream fileOutputStream = new FileOutputStream("d:\\buffered.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
for (int i = 0; i < 2; i++) {
bufferedOutputStream.write("hello world\n\r".getBytes(StandardCharsets.UTF_8));//写入8k缓冲区,\n\r是隔行换行
bufferedOutputStream.flush();//刷新否则输出的结果不显示
}
//关闭(关闭的时候会自动调用一次flush方法)
bufferedOutputStream.close();//关闭这个相当于同时关闭fileOutputStream
}
}
对象流
使用流传出对象的过程称为序列化、反序列化
序列化:写入文件
反序列化:读取文件
序列化
package IO;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/*
使用ObjectOutputStream实现对象的序列化
??这条保留意见:要实现序列化就要让Student继承Serializable接口,让它标记为可序列化的类
* */
public class Demo06ObjectOutputStream {
public static void main(String[] args) throws Exception{
//创建对象流
FileOutputStream fileOutputStream = new FileOutputStream("d:\\stu.bin");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
//序列化:写入操作
Student zhangsan = new Student(10, "zhangsan");
objectOutputStream.writeObject(zhangsan);
//关闭流
fileOutputStream.close();
objectOutputStream.close();
}
}
反序列化
package IO;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/*使用ObjectInputStream实现反序列化(读取重构成对象)
* */
public class Demo07ObjectInputStream {
public static void main(String[] args) throws Exception{
FileInputStream fileInputStream = new FileInputStream("d:\\stu.bin");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
//读取文件(反序列化)
Student s=(Student) objectInputStream.readObject();//没有强转之前是Object类型
//反序列化,也就是前面一行只能执行一次,否则就会出现异常
//关闭
fileInputStream.close();
objectInputStream.close();
System.out.println(s.toString());
}
}
序列化注意事项
集合序列化的用法:
/*要写入多个对象的时候直接new ArrayList,然后写入list就可以
* 反序列的时候
* ArrayList<Student> students = (ArrayList<Student>)ObjectInputStream.readObject();
*直接输出list.toString就可以
* */
为什么需要序列化
如果要将“文本,图片,视频等信息储存在电脑中,就需要序列化(也就是将文本,图片,视频等信息转化为二进制数据,保存在电脑中)”
字符流
常见字符编码(省略)
文件字符输入流
package IO;
import java.io.FileReader;
/*文件字符输入流:用作读取一个个的字符的方法
*
* */
public class Demo08FileReader {
public static void main(String[] args) throws Exception{
FileReader fileReader = new FileReader("d:\\aaa.txt");
//第一种方法,遍历里面所有的字符
int a;
while ((a=fileReader.read())!=-1){
System.out.println((char)a);
}
//第二种方法,设置数组输出字符
/* int a;
char a1[]=new char[4];
while ((a=fileReader.read(a1))!=-1){
System.out.println(new String(a1,0,a));
}*/
fileReader.close();
}
}
文件字符输出流
package IO;
import java.io.FileWriter;
/*文件字符输出流
*
* */
public class Demo09FileWriter {
public static void main(String[] args) throws Exception{
FileWriter fileWriter=new FileWriter("d:\\writer.txt");
for (int i = 0; i < 10; i++) {
fileWriter.write("java是这个世界上最好的语言\n\r");
fileWriter.flush();
}
fileWriter.close();
}
}
文件字符流输出流复制文本文件字符输入流
package IO;
import java.io.FileReader;
import java.io.FileWriter;
/*文件字符流输出流复制文本文件字符输入流,不能复制图片和二进制文件
字节流可以复制任意的文件
*
* */
public class Demo10FileReaderWriter {
public static void main(String[] args) throws Exception{
FileReader fileReader = new FileReader("d:\\writer.txt");
FileWriter fileWriter = new FileWriter("d:\\writer2.txt");
int date;
while ((date=fileReader.read())!=-1){
fileWriter.write(date);
fileWriter.flush();
}
fileReader.close();
fileWriter.close();
}
}
文件字节缓冲输入流
package IO;
import java.io.BufferedReader;
import java.io.FileReader;
/*字符缓冲流读取文件
* */
public class Demo11BufferedReader {
public static void main(String[] args) throws Exception{
FileReader fileReader = new FileReader("d:\\writer.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
/*第一种方法
int a;
char[] a1=new char[1024];
while ((a=bufferedReader.read(a1))!=-1){
System.out.println(new String(a1,0,a));
}*/
//第二种方法:一行一行的输出
String Line=null;
while ((Line=bufferedReader.readLine())!=null){
System.out.println(Line);
}
bufferedReader.close();//关闭这个相当于同时关闭fileReader
}
}
文件字符缓冲输出流
package IO;
import java.io.BufferedWriter;
import java.io.FileWriter;
/*文件字节输出流缓冲流
换行有多出来一个new Line,可以直接换行,相当于写入一个\r\n
* */
public class Demo12BufferedWriter {
public static void main(String[] args) throws Exception{
FileWriter fileWriter = new FileWriter("d:\\buffered.txt");
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
for (int i = 0; i < 10; i++) {
bufferedWriter.write("好好学习,天天向上");
bufferedWriter.newLine();//相当于写入一个\r\n
bufferedWriter.flush();
}
bufferedWriter.close();
}
}
打印输出流
package IO;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
/*打印输出流:PrintWriter
*
* */
public class Demo13PrintWriter {
public static void main(String[] args) throws Exception {
PrintWriter printWriter = new PrintWriter("d:\\print.txt");
printWriter.println("随便的名字");
printWriter.println('a');
printWriter.println(7456874);
printWriter.close();//千万记得一定要关闭,否则就不会输出显示的东西
}
}
转换流
转换输入流
package IO;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/*字节流通向字符流的转换流,指定使用的编码
*
* */
public class Demo14InputStreamReader {
public static void main(String[] args) throws Exception{
FileInputStream fileInputStream = new FileInputStream("d:\\writer.txt");
//要保证存储的文件格式和设定编码的文件格式一致、gbk对应的额文件格式就是ANSI
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
int a;
while ((a=inputStreamReader.read())!=-1){
System.out.print((char) a);
}
inputStreamReader.close();
}
}
转换输出流
package IO;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
/*使用指定编码转换输出流
*
* */
public class Demo15OutputStreamReader {
public static void main(String[] args) throws Exception{
FileOutputStream fileOutputStream = new FileOutputStream("d:\\info.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"gbk");
for (int i = 0; i < 10; i++) {
outputStreamWriter.write("我其实也不知道写什么\n\r");
outputStreamWriter.flush();
}
outputStreamWriter.close();
}
}
File操作(文件、文件夹、过滤文件操作)
package IO;
import lesson04.snake.Date;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
/*文件操作
* 1.路径分隔符
* 2.名称分隔符
*
*
* */
public class Demo16File {
public static void main(String[] args) throws Exception {
File file = new File("d:\\file.txt");
a();
a1();
a2();
}
//1分隔符操作
public static void a(){
System.out.println("路径分隔符+"+File.pathSeparator);
System.out.println("名称分隔符+"+File.separator);
}
//2文件操作
public static void a1() throws Exception {
//2.1.创建文件
File file = new File("d:\\file.txt");
System.out.println(file.toString());
if (!file.exists()){ //因为布尔值再次运行的时候会出现错误,所以用file.exists()存在的时候即运行就可以判断有没有存在文件
boolean newFile = file.createNewFile();//再次运行的时候布尔值就为false
System.out.println("创建结果+"+newFile);
}
//2.2删除文件
//System.out.println(file.delete());
//2.2使用jvm退出时删除
file.deleteOnExit();
Thread.sleep(5000);//毫秒为单位
//2.3获取文件信息
System.out.println("绝对路径"+file.getAbsoluteFile());
System.out.println("获取路径"+file.getPath());
System.out.println("获取文件名"+file.getName());
System.out.println("获取父类路径"+file.getParent());
System.out.println("获取文件长度"+file.length());
System.out.println("获取文件创建时间"+new Date(file.lastModified()).toString());
//2.4判断
System.out.println("是否可读"+file.canRead());
System.out.println("是否可写"+file.canWrite());
System.out.println("是否是文件"+file.isFile());
System.out.println("是否隐藏"+file.isHidden());
}
//3文件夹操作
public static void a2() throws Exception {
//3.1创建文件夹
File file = new File("d:\\aa\\bb\\cc");
if (!file.exists()){
//file.mkdir();//这个是只能创建单级目录
System.out.println(file.mkdirs());
}
//3.2删除文件夹(两种方法——删除的都是最里层的文件夹)
//3.2.1
//System.out.println(file.delete());
//3.2.2
file.deleteOnExit();
Thread.sleep(5000);
//3.3获取文件夹信息(同上文件操作的方法)
//3.4判断(大部分同上文件操作的方法)
System.out.println("是否是文件夹"+file.isDirectory());
//3.5遍历文件夹
File file1 = new File("d:\\图片");
String[] list = file1.list();
for (String s : list) {
System.out.println(s);
}
FileFilter fileFilter = new FileFilter() {
@Override
public boolean accept(File pathname) {
return false;
}
};
File[] file2=file1.listFiles(new FileFilter() { //filter是过滤器的意思
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".jpg")){ //path是路径的意思
return true;
}
return false;
}
});
System.out.println("========FileFilter接口的使用=================");
for (File file3 : file2) {
System.out.println(file3.getName());
}
}
}
递归遍历、递归删除
package IO;
import java.io.File;
/*递归遍历和递归删除
*递归删除文件夹就首先需要把文件夹里面的文件删除之后方可
*疑问点:
怎么删除没有文件的文件夹
* */
public class Demo17ListDir {
public static void main(String[] args) {
//listDir(new File("d:\\myfile"));
deleteDir(new File("d:\\myfile"));
}
//递归遍历文件夹
public static void listDir(File dir){
File[] files = dir.listFiles(); //文件的列表文件
if (files!=null&&files.length>0){
for (File file : files) { //遍历文件
if (file.isDirectory()){ //判断是不是文件夹
listDir(file); //这里用到了递归
}else {
System.out.println(file.getAbsoluteFile());//绝对路径
}
}
}
System.out.println("===========递归删除文件夹=====================");
}
//递归删除文件夹
public static void deleteDir(File dir){
File[] files = dir.listFiles();
if (files.length>0&&files!=null){
for (File file : files) {
if (file.isDirectory()){
deleteDir(file); //如果是文件夹那就继续递归,如果不是文件夹就需要先删除里面的文件才可以删除文件夹,
}else {
System.out.println(file.getAbsoluteFile()+"删除"+file.delete());
}
}
System.out.println(dir.getAbsoluteFile()+"删除文件夹"+dir.delete());//切记必须文件夹里面有文件才有这个递归删除,否则直接删除空白文件夹是不能操作的
}
}
}
Properties(属性)(保存、加载属性、属性值)
package IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;
/*属性集合
*
* */
public class Demo18Property {
public static void main(String[] args) throws Exception{
Properties properties = new Properties();
//设置属性
properties.setProperty("姓名1","张三");
properties.setProperty("年龄","15");
System.out.println(properties.toString());
//遍历
//keySet
//entrySet
//stringPropertyNames()
Set<String> a=properties.stringPropertyNames(); //设置字符串性质的名字
for (String s : a) {
System.out.println(s+"===="+properties.getProperty(s));
}
//和流有关的方法(打印保存属性、属性名)
System.out.println("====和list有关的方法========");
PrintWriter printWriter = new PrintWriter("d:\\print.txt");
properties.list(printWriter);//和下面一起的两种方法都可以互相调用使用
printWriter.println(properties);
printWriter.close();
//=========store方法(保存)=========
FileOutputStream fileOutputStream = new FileOutputStream("e:\\store.properties");
properties.store(fileOutputStream,"zhushi");
fileOutputStream.close();
//==========load(加载)==============
Properties properties1 = new Properties();
FileInputStream fileInputStream = new FileInputStream("e:\\store.properties");
properties1.load(fileInputStream);
fileInputStream.close();
System.out.println(properties1.toString());
}
}