JavaSE---IO流

一、File类

1.1 File

概念:表示操作系统磁盘上的文件或者是文件夹

路径:

  • 相对路径 (相对于当前工程的根路径)
  • 绝对路径 (在磁盘上的完整路径)

常见方法

方法名描述
createNewFile()创建一个新文件。
mkdir()创建一个新目录。如果父目录不存在,则无法创建
mkdirs()创建一个新目录。如果父目录不存在,则一起创建
delete()删除文件或空目录。
exists()判断File对象所对象所代表的对象是否存在。
length()获取文件(夹)的大小(字节)
getAbsolutePath()获取文件的绝对路径。
getAbsoluteFile()获取文件(夹)的绝对路径:(返回File)
getName()获取当前file对象的文件名或者是文件夹名
getParent()获取当前file对象的父目录(返回String)
isDirectory()是否是目录。
isFile()是否是文件。
getPath()获取文件(夹)的相对路径:(返回String)
listFiles()列出目录中的所有内容。
//创建File对象
File file = new File("d:\\a.txt");
if(!file.exists()) {
    //创建文件
    file.createNewFile();
}
System.out.println("判断文件或者是文件夹是否存在"+file.exists());
System.out.println("判断是否是文件:"+file.isFile());
System.out.println("判断是否是文件夹:"+file.isDirectory());
System.out.println("获取文件或者文件夹的名字:"+file.getName());
System.out.println("获取文件大小(字节):"+file.length());
System.out.println("获取文件的相对路径:"+file.getPath());
System.out.println("获取文件的绝对路径(String):"+file.getAbsolutePath());
System.out.println("获取文件的绝对路径(File):"+file.getAbsoluteFile());
System.out.println("获取文件的父目录(String):"+file.getParent());
System.out.println("获取文件的父目录(File):"+file.getParentFile());


System.out.println("获取文件所在位置磁盘的总空间:"+file.getTotalSpace());
System.out.println("获取文件所在位置磁盘的可用空间:"+file.getFreeSpace());
System.out.println("获取文件的最后修改时间(毫秒)"+file.lastModified());
System.out.println("判断文件是否可读"+file.canRead());
System.out.println("判断文件是否可写"+file.canWrite());
System.out.println("判断文件是否可执行"+file.canExecute());
System.out.println("判断文件是否是隐藏文件"+file.isHidden());

1.2 FileNameFilter接口

FileNameFilter:文件过滤器接口

  • boolean accept(File pathname)。
  • 当调用File类中的listFiles()方法时,支持传入FileNameFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中。

案例:使用文件过滤器获取所有java文件

File[] files = f.listFiles(new FilenameFilter() {
    @Override
    public boolean accept(File dir, String name) {
        return name.endsWith(".java");
    }
});
for (File file2 : files) {
    System.out.println(file2.getName());
}

1.3 文件搜索案例

遍历出某文件夹中的所有的java文件

public class FileDemo02 {
	public static void main(String[] args) {
		getJavaFile(new File("d:\\zz"));
	}
	//思考:删除一个文件夹	
	
	//思考:获取文件夹下所有的java文件
	public static void getJavaFile(File file) {
		//遍历当前文件夹下所有的文件或者是文件
		File[] files = file.listFiles();
		//f有两种情况,文件或者是文件夹
		for (File f : files) {
			if(f.isFile()) {
				if(f.getName().endsWith(".java")) {
					System.out.println(f.getName());
				}
			}else {
				//递归调用getJavaFile
				getJavaFile(f);
			}
		}
	}	
}

二、IO流

2.1 概念

  • 内存与存储设备之间传输数据的通道。
  • 水借助管道传输;数据借助流传输。

2.2 流的分类

2.2.1 按方向

  • 输入流:将<存储设备>中的内容读入到<内存>中。
  • 输出流:将<内存>中的内容写入到<存储设备>中。

2.2.2 按单位

  • 字节流:以字节为单位,可以读写所有数据 。
  • 字符流:以字符为单位,只能读写文本数据 。

2.2.3 按功能

  • 节点流:具有实际传输数据的读写功能。
  • 过滤流:在节点流的基础之上增强功能。

三、字节流【重点】

3.1 字节抽象类

InputStream:字节输入流

  • public int read(){}。
  • public int read(byte[] b){}。
  • public int read(byte[] b,int off,int len){}。

OutputStream:字节输出流

  • public void write(int n){}。
  • public void write(byte[] b){}。
  • public void write(byte[] b,int off,int len){}。

3.2 文件字节流【重点】

FileOutputStream

  • out.write(int b);
    • 一次写入一个字节,整数表示这个字节对应ASCII码值
  • out.write(byte b);
    • 一次写入一个字节数组的内容
  • out.write(b, off, len);
    • 参数2:从数组的指定位置开始
    • 参数3:执行写出的字节个数
    • 一次写入一个字节数组的内容

FileInputStream

  • fis.read();
    • 一次读取一个字节,返回这个字节所对应的ASCII值,如果读到流的末尾返回-1
  • fis.read(byte[] b);
    • 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1
  • fis.read(byte[] b,int offset,int len);
    • 参数2:读取到数组中指定起始位置
    • 参数3: 指定读取的字节个数
    • 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1

文件字节输入流FileInputStream

public class FileInputStreamDemo {
	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			//一、创建流对象
			fis = new FileInputStream("a.txt");
			
			//二、通过流对象进行读或者写
			/*
			 * 方法1:read()
			 *    一次读取一个字节,返回这个字节所对应的ASCII值,如果读到流的末尾返回-1
			 */
//			System.out.println(fis.read());
//			System.out.println(fis.read());
//			System.out.println(fis.read());
//			System.out.println(fis.read());
			
			/**
			 * 方法2:fis.read(b)
			 *    从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返 回-1
			 *  
			 */
			//自定义缓冲区
//			byte[] buf = new byte[1024]; 
//			int len = fis.read(buf);
//			//将byte数组转换成String字符串
//			String str = new String(buf,0,len);
//			System.out.println(str);
			
			//自定义缓冲区
//			byte[] buf = new byte[1024];
//			int len;
//			while( (len = fis.read(buf))  !=  -1) {
//				String str = new String(buf,0,len);
//				System.out.println(str);
//			}
			/**
			 * 方法3:fis.read(buf,offset,len);
			 * 	       参数2:读取到数组中指定起始位置
			 *     参数3: 指定读取的字节个数
			 * 
			 * 	从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1
			 */
			//自定义缓冲区
			byte[] buf = new byte[1024];
			fis.read(buf, 2, 3);
			System.out.println(Arrays.toString(buf));			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//三、关闭流对象
			try {
				if(fis != null)
					fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}			
		}	
	}
}

文件字节输入流FileOutputStream

public class FileOutputStreamDemo {
	public static void main(String[] args) {
		//一、创建流对象
		FileOutputStream fos =  null;
		try {
			fos = new FileOutputStream(new File("b.txt"));
			//二、通过流对象进行读或者写
			/**
			 * fos.write(int b)
			 * 	 一次写入一个字节,整数表示这个字节对应ASCII码值
			 */
			//fos.write(97);
			
			/**
			 * fos.write(byte[] b);
			 * 	一次写入一个字节数组的内容
			 */
			//byte[] b = "你好".getBytes();
			//fos.write(b);
			
			/**
			 * fos.write(byte[] b,int offset,int len);
			 * 			参数2:从数组的指定位置开始
			 *          参数3:执行写出的字节个数
			 * 
			 * 一次写入一个字节数组的内容
			 */
			byte[] b = "你好吗?".getBytes();
			//System.out.println(Arrays.toString(b));
			//fos.write(b, 2, 6);
			fos.write(b,0,b.length);
            
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//三、关闭流对象
			try {
				if(fos != null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}	
	}
}

3.3 IO流细节

  • 1、在使用文件输出流的时候如果文件不存在会自动创建,但是要保证其父目录存在
  • 2、在使用文件输出流的时候,如果想要向文件中追加内容,那么需要将构造参数append设置为true
  • 3、在使用IO读写的时候,读写的操作应当写在try代码块中,关闭资源的代码写在finally代码块中
  • 4、将IO流的创建写在try()中,这样IO流在使用完成之后无需关闭

3.4 字节缓冲流【重点】

缓冲流:BufferedOutputStream/BufferedInputStream

  • 提高IO效率,减少访问磁盘的次数。
  • 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
public class BufferedSteamDemo {
	public static void main(String[] args) throws Exception {
//		//一、创建缓冲流流对象
//		FileInputStream fis = new FileInputStream("c.txt");
//		BufferedInputStream bis = new BufferedInputStream(fis);
//		
//		//二、通过流对象进行读写
//		byte[] buf = new byte[1024];
//		int len;
//		while((len = bis.read(buf) ) != -1) {
//			String str = new String(buf, 0, len);
//			System.out.println(str);
//		}
//		
//		//三、关闭流资源(后用先关闭)
//		bis.close();
//		fis.close();
		
		
		//一、创建缓冲流流对象
		FileOutputStream fos = new FileOutputStream("d.txt");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		//二、通过流对象进行读写
		bos.write("hello,缓冲流".getBytes());
		//刷新(将缓冲区的内容刷新到目的地(硬盘))
		bos.flush();
        
		//三、关闭流资源(后用先关闭)
		//关闭流资源的时候,会自动刷新缓冲区内容。(只会刷新一次)
		bos.close();
		fos.close();		
	}
}

3.5综合案例(文件拷贝)

public class FileCopyDemo {
	public static void main(String[] args) {
		copy2();
	}
	public static void copy1() {
		long start = System.currentTimeMillis();
		
		FileInputStream fis =  null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("C:\\Users\\hawa\\Desktop\\Java2105班\\上课视频\\1阶段.zip");
			fos = new FileOutputStream("d:\\1.zip");
			
			//定义缓冲区(一次读取1024个字节)
			byte[] buf = new byte[1024];
			int len;
			while((len = fis.read(buf)) != -1) {
				fos.write(buf,0,len);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(fis!=null)
					fis.close();
				if(fos!=null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		long end = System.currentTimeMillis();
		
		//字节流耗时:147035
		System.out.println("字节流耗时:"+(end - start));
	}
	public static void copy2() {
		long start = System.currentTimeMillis();
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		try {
			fis = new FileInputStream("C:\\Users\\hawa\\Desktop\\Java2105班\\上课视频\\1阶段.zip");
			fos = new FileOutputStream("d:\\1.zip");
			
			bis = new BufferedInputStream(fis,80*1024);
			bos = new BufferedOutputStream(fos,80*1024);
			
			byte[] buf = new byte[1024];
			int len;
			while((len = bis.read(buf)) !=-1) {
				bos.write(buf, 0, len);
				//刷新一次就相当于磁盘之间的一次IO操作,会降低效率
				//bos.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(fis!=null)
					fis.close();
				if(bis != null) 
					bis.close();
				if(bos!=null)
					bos.close();
				if(fos!=null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		long end = System.currentTimeMillis();
		//缓冲流耗时:106388
		System.out.println("缓冲流耗时:"+(end - start));
	}
}

3.6 对象流【重点】

对象流:ObjectOutputStream/ObjectInputStream

  • 增加了缓冲区功能。
  • 增加了读写8种基本数据类型和字符串功能。
  • 增加了读写对象的功能:
    • readObject() 从流中读取一个对象。
    • writeObject(Object obj) 向流中写入一个对象

3.6.1 对象流读写基本操作

//============对象流读写基本类型+String类型============
		
//一、创建流对象
FileOutputStream fos = new FileOutputStream("e.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//二、通过对象流进行读写
oos.writeInt(97);         //Integer
oos.writeDouble(100.25);  //Double
oos.writeUTF("对象流");    //String
//三、关闭流资源
oos.close();
fos.close();

//一、创建流对象
FileInputStream fis = new FileInputStream("e.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
//二、通过对象流进行读写  (读取的顺序和写入的顺序要一致)
System.out.println(ois.readInt());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
//三、关闭流资源
ois.close();
fis.close();

3.6.2 对象流读写对象

对象流写操作(序列化)

//============对象流读写对象============

//写入对象
FileOutputStream fos = new FileOutputStream("f.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);

User user = new User("cxk", 30);
oos.writeObject(user);

oos.close();
fos.close();

对象流写操作(反序列化)

//读取对象
FileInputStream fis = new FileInputStream("f.txt");
ObjectInputStream ois = new ObjectInputStream(fis);

User user1 = (User) ois.readObject();
System.out.println(user1);

ois.close();
fis.close();

实体类(必须要实现序列化接口)

class User implements Serializable{
	String name;
    int age;
	//.....
}

3.6.3对象流读写合集

//============对象流读写List集合============
//写入对象
FileOutputStream fos = new FileOutputStream("f.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);

User user1 = new User("cxk1", 31);
User user2 = new User("cxk2", 32);
User user3 = new User("cxk3", 33);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
oos.writeObject(userList);

oos.close();
fos.close();

//读取对象
FileInputStream fis = new FileInputStream("f.txt");
ObjectInputStream ois = new ObjectInputStream(fis);

List<User> users = (List<User>) ois.readObject();
System.out.println(users);
List<User> users1 = (List<User>) ois.readObject();

ois.close();
fis.close();

3.6.4 对象流使用细节

序列化的细节:

  • 1、对象流读到流的末尾,会抛出异常EOFException
  • 2、如果属性不想被序列化,那么可以使用transient关键字修饰
  • 3、类实现了Serializable接口,会自动生成一序列化id(序列化和反序列的id要保证一致)

3.7 数据流

DataInputStreamDataOutputStream是过滤流,封装了对基本数据类型加String的读和写的操作

方法与对象流一致(省略)

四、字符流【重点】

4.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(String str,int offset,int len){}。
  • public void write(char[] c){}。
  • public void write(char[] c,int offset,int len){}。

4.2 文件字符流【重点】

文件字符输入流

public class FileReaderAndWriterDemo2 {
	public static void main(String[] args) throws Exception {
		//一、创建字符流对象
		FileReader fr = new FileReader("h.txt");
		
		//二、通过流对象读写数据
		/**
		 * fr.read()
		 * 	一次读取一个字符,并返回这个字符在Unicode码表中的值,如果读到流的末尾返回-1
		 */
		//System.out.println(fr.read());
		//System.out.println(fr.read());
		
		
		/**
		 * fr.read(char[] ch)
		 * 	一次读取一个字符数组,并返回读取到的字符的长度,如果读到流的末尾返回-1
		 */
//		char[] cbuf = new char[1024];
//		int len;
//		while((len = fr.read(cbuf)) != -1) {
//			String str = new String(cbuf, 0, len);
//			System.out.println(str);
//		}
		
		/**
		 * fr.read(char[] ch,int offset,int len)
		 * 		参数2:指定存放在数组中的起始位置       参数3:指定存放字符的长度
		 * 	一次读取一个字符数组,并返回读取到的字符的长度,如果读到流的末尾返回-1
		 */
		char[] cbuf = new char[1024];
		fr.read(cbuf, 3, 10);
		System.out.println(Arrays.toString(cbuf));
		
		//三、关闭流资源
		fr.close();
	}
}

文件字符输出流Filewrite

public class FileReaderAndWriterDemo {
	public static void main(String[] args) throws Exception {
		//一、创建字符流对象
		FileWriter fw = new FileWriter("h.txt");
		
		//二、通过流对象读写数据
		
		/**
		 * write(int b)
		 * 	写入一个字符,整数表示这个字符在Unicode码表中的值
		 */
		//fw.write(97);
		//fw.write(20320);
		
		/**
		 * write(char[] ch)
		 *   写入一个字符数组
		 */
		//String str = "你真棒";
		//fw.write(str.toCharArray());
		
		/**
		 * write(String str)
		 *   写入一个字符串
		 */
		//fw.write("你好真棒!!!");
		
		
		/**
		 * write(char[] ch,int offset,int len)
		 * 		参数2:可以指定数组的起始位置      参数3:可以指定写入的字符长度
		 *   写入一个字符数组
		 */
		
		//String str = "你真棒";
		//fw.write(str.toCharArray(), 1, 2);
		
		/**
		 * write(String str)
		 * 	    参数2:可以指定字符串的起始位置      参数3:可以指定写入的字符长度
		 *   写入一个字符串
		 */
		fw.write("你好真棒!!!", 1, 2);
		
		//三、关闭流资源
		fw.close();
	}
}

4.3 字符缓冲流

缓冲流:BufferedWriter/BufferedReader

  • 支持输入换行符
  • 可一次写一行、读一行。
public class BufferedDemo {
	public static void main(String[] args) throws Exception {
		//1、创建字符串缓冲输入流
		BufferedReader br = new BufferedReader(new FileReader("d:\\a.txt"));
		//2、通过字符缓冲流读取内容
		//一次一行内容,读到文件末尾返回null
		//System.out.println(br.readLine());
		String line;
		while((line = br.readLine()) != null) {
			System.out.println(line);
		}
		//3、关闭资源
		br.close();
		
		//1、创建字符缓冲输出流
		BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\ddd.txt"));
		bw.write("BufferedWriter。。。。。");
		//写入一个换行
		bw.newLine();
		bw.write("第二行。。。。。");
		//3、关闭资源
		bw.close();
	}
}

4.4 转换流

转换流:InputStreamReader/OutputStreamWriter

  • 可将字节流转换为字符流。
  • 可设置字符的编码方式。

将字节输入流转换成字符输入流,并设置编码

public class InputStreamReaderDemo {
	public static void main(String[] args) throws Exception {
		//1、创建字节流对象
		FileInputStream fis = new FileInputStream("d:\\a.txt");
		//2、将字节流装换成字符流
		InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
		//3、将字符流包装成字符缓冲流
		BufferedReader br = new BufferedReader(isr);
		String line;
		while( (line = br.readLine()) != null) {
			System.out.println(line);
		}
		br.close();
		//OutputStreamWriter  将字节输出流转换成字符输出流
	}
}

4.5 打印流

  • 字节打印流
  • 字符打印流

打印流中提供了一组可以直接写出基本类型和String的方法

注意:打印流中的print(Object obj)方法并不是写出对象,而是写出对象的toString方法的返回值

public class PrintDemo {
	public static void main(String[] args) throws Exception {
		//1、创建字节打印流
		PrintStream ps = new PrintStream("D:\\aaaa.txt");
		//printXXX方法
		ps.print(10);
		//换行
		ps.println("dsadsa");
		ps.print("哈哈print流");
		//注意:写入的是对象字符串变现形式(toString方法的结果)
		ps.print(new Student());
		ps.close();		
		
		//2、创建字符打印流
		PrintWriter pw = new PrintWriter("D:\\aaaa.txt");
		pw.print("哈哈");
		pw.println();
		pw.print(1000);
		pw.close();
	}
}

五、字符编码

  • 字符
    • 各个国家的文化符号
  • 字符集
    • 将文化符号进行统一收集生成字符集合(字典)
  • 字符编码
    • 每一种字符集 对字符的编排
  • 常见字符集 : ASCIIGBKUnicode(万国码)
  • 常见的字符编码:
    • ASCII编码 GBK编码 UTF-8 UTF-16 UTF-32 ISO8859-1 Big5 GB2312 GB18030
  • ASCII编码
    • 美国信息交换标准代码 最多只能表示256个字符
    • 一个字符 = 一个字节
  • GBK编码
    • 国标码 前身是GB2312
    • 如果是0~256 ASCII码中的字符 。 一个字符 = 一个字节
    • 其他情况 一个字符 = 两个字节
  • UTF-8 编码
    • 可变字符
    • 如果是0~128 ASCII码中的字符 一个字符 = 一个字节
    • 如果是128~2048 Unicode码表中的字符 一个字符 = 两个字节
    • 如果是2048 ~65535 Unicode码表的字符 一个字符 = 三个字节
  • 编码:
    • 将程序的内容写入到目的地,就是编码过程
  • 解码:
    • 将目的地的内容读取到程序中,就是解码过程
  • 为什么会出现乱码?
    • 编码和解码的编码方式不一致
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值