一、File类

概念

  • 代表物理盘符中的一个文件或者文件夹

常见方法

**exists()** 文件是否存在
isDirectory() 是否是目录
isFile() 是否是文件
length() 返回文件长度
**getName()** 文件的名字
getAbsolutePath() 获取文件绝对路径
**createNewFile()** 创建一个新的文件
**delete()** 删除文件
getParent() 上级目录
mkdir() 创建一个新目录
listFiles() 列出目录中的所有内容

跟文件相关的

  1. public static void main(String[] args) throws IOException {
  2. //创建文件对象
  3. File f = new File("d:/test");
  4. File f1 = new File("d:\\test");
  5. /*
  6. File.separator获取当前操作系统的路径拼接符号
  7. File file2 = new File("d:"+File.separator+ "test");
  8. */
  9. System.out.println("文件是否可读:" + f.canRead());
  10. System.out.println("文件是否可写:" + f.canWrite());
  11. System.out.println("文件的名字:" + f.getName());
  12. System.out.println("上级目录:" + f.getParent());
  13. System.out.println("是否是一个目录:" + f.isDirectory());
  14. System.out.println("是否是一个文件:" + f.isFile());
  15. System.out.println("是否隐藏:" + f.isHidden());
  16. System.out.println("文件的大小:" + f.length());
  17. System.out.println("是否存在:" + f.exists());
  18. System.out.println("比较两个对象对应的文件路径:" + f.equals(f1));
  19. System.out.println("绝对路径路径:" + f.getAbsolutePath());
  20. System.out.println("相对路径:" + f.getPath());
  21. System.out.println("toString:" + f.toString());//相当于相对路径
  22. if (f.exists()) {//如果文件存在,将文件删除操作
  23. f.delete();
  24. } else { //如果文件不存在,就创建这个文件
  25. f.createNewFile();
  26. }
  27. }
  28. }

跟目录相关的

  1. public class File01 {
  2. public static void main(String[] args) {
  3. //创建文件对象
  4. File f = new File("d:/test");
  5. f.mkdir();//创建单层目录
  6. f.mkdirs();//创建多层目录
  7. f.delete();//只会删除一层,并且这层目录是空的,如果有内容就不会删除
  8. //查看文件下的目录
  9. File[] files = f.listFiles();
  10. for(File file:files){
  11. System.out.println(file.getAbsolutePath());
  12. }
  13. }
  14. }

二、io流

iO流用来处理设备之间的数据传输,io流形象地理解一个“管子”,程序和数据源直接**沟通**的桥梁

IO流分类

  1. 方向:输入流 和 输出流
  2. 内容:字节流 和 字符流

IO流体系

未命名文件.png

经验 , Stream结尾的为字节流 Reader Writer为字符流

三、字节流

文件流

以字节形式读取文件数据,通常适用于读二进制文件 如图片 视频 音频文件等。

输入流 FileInputStream

方式1

  1. public static void main(String[] args) throws IOException {
  2. //1. 创建流对象
  3. FileInputStream fis = new FileInputStream("G:\\LOL.jpg");
  4. // 2. 读数据
  5. int count = 0;//定义一个计数器,用来计读入的字节个数
  6. int n = frs.read();
  7. while(n! = -1){
  8. count++;
  9. System.out.print(n);
  10. n= frs.read();
  11. }
  12. System.out.print(count);
  13. // 3.关闭流
  14. fis.close();
  15. }

方式2

  1. public static void main(String[] args) throws IOException {
  2. //1. 创建流对象
  3. FileInputStream fis = new FileInputStream("G:\\LOL.jpg");
  4. // 2. 读数据
  5. byte[] buff = new byte[6];// 准备临时存放容器,用于每次存储读取的数据
  6. int len = 0;//本次读取的实际字节数
  7. //循环读取字节
  8. while ((len = fis.read(buff)) != -1) {
  9. String s = new String(buff, 0, len);
  10. System.out.println(s);
  11. }
  12. // 3.关闭
  13. fis.close();
  14. }

注意事项

  • 文件是**utf-8**进行存储的,**英文字符**:底层占用**1个字节****中文字符**,底层占用**3个字节**
  • 如果文件是文本文件,不要使用字节流读取,建议使用字符流
  • **read()**读取一个字节,返回值是int类型,而不是byte类型,这是因为read方法底层做了处理,让繁华的数据都是**正数**,就是为了避免如果字节繁华的是-1,那么到底是读入的字节,还是文件结尾呢

输出流 FileOutStream

  1. public class FileOutputStreamCase {
  2. public static void main(String[] args) throws IOException {
  3. //1. 创建流
  4. FileOutputStream fos = new FileOutputStream("G:\\LOL.jpg",true);
  5. //2. 写数据
  6. String massage = "我喜欢景甜";
  7. fos.write( massage.getBytes() );
  8. //3 . 关闭流
  9. fos.close();
  10. }
  11. }

功能:完成图片复制

  1. public class Test {
  2. public static void main(String[] args) {
  3. //源图片
  4. File f1 = new File("G:\\LOL.jpg");
  5. //目标图片
  6. File f2 = new File("G:\\LOL.jpg");
  7. //创建输入流对象
  8. FileReader fr = new FileInputStream(f1);
  9. //创建输出流对象
  10. FileWriter fw = new FileOutputStream(f2);
  11. //【方式1 读数据 写数据】
  12. int n = fis.read();
  13. while(n! = -1){
  14. fw.write(n)
  15. n= fis.read();
  16. }
  17. //【方式2 利用缓冲字符数组】
  18. byte[] b = new byte[5];
  19. int len = fis.read(b);
  20. while(len != -1){
  21. fw.write(b,o,len)//将缓冲数组中有效长度写出
  22. len = fis.read(b);
  23. }
  24. //关闭流(关闭流的时候,倒着关闭,后用先关)
  25. fos.close();
  26. fis.close();
  27. }
  28. }

缓存流

没有特别功能,指定提供了缓冲,优先从缓存中读写,降低和IO设备访问次数提高效率。

输入流 BufferedInputStream

  1. public static void main(String[] args) throws IOException {
  2. //1. 创建流
  3. BufferedInputStream bis =
  4. new BufferedInputStream(
  5. new FileInputStream("G:\\LOL.jpg"));
  6. //2. 读文件
  7. byte[] buff = new byte[1024];
  8. int len = 0;
  9. while( (len=bis.read(buff)) !=-1 ){
  10. String xx = new String( buff, 0 , len );
  11. System.out.println(xx);
  12. }
  13. //3.关闭
  14. bis.close();
  15. }

输出流 BufferedOutputStream

  1. public static void main(String[] args) throws IOException {
  2. //1. 创建流
  3. BufferedOutputStream bos =
  4. new BufferedOutputStream(
  5. new FileOutputStream("G:\\LOL.jpg) );
  6. //2. 写数据
  7. String massage = "q床前明月光,疑是地上霜q";
  8. bos.write( massage.getBytes() );
  9. bos.flush(); //缓冲流的方法
  10. //3. 关闭流
  11. bos.close();
  12. }
  1. public class Test {
  2. public static void main(String[] args) {
  3. //1. 源图片
  4. BufferedInputStream bis =
  5. new BufferedInputStream(
  6. new FileInputStream("G:\\LOL.jpg"));
  7. //1. 目标图片
  8. BufferedOutputStream bos =
  9. new BufferedOutputStream(
  10. new FileOutputStream("G:\\LOL1.jpg) );
  11. //利用缓冲字符数组
  12. byte[] b = new byte[1024*5];
  13. int len = bis.read(b);
  14. while(len != -1){
  15. bos.write(b,o,len)//将缓冲数组中有效长度写出
  16. len = bis.read(b);
  17. }
  18. //关闭流(
  19. bos.close();
  20. bis.close();
  21. }
  22. }

对象流

对象流作用是,可以把一个对象写到文件中,或者把一个文件中的对象,读取到内存。它就是序列化和反序列化的流:
序列化: 把对象二进制信息 写入流。
反序列化: 从流中读取对象的二进制信息,还原到内存。

序列化流ObjectOutputStream

  1. public static void main(String[] args) throws IOException {
  2. //1 创建流
  3. ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("obj.dat") );
  4. //2. 写数据:将内存中的字符串写到文件中
  5. oos.writeInt("你好");
  6. //3.关闭
  7. oos.close();
  8. }

反序列化流ObjectInputStream

  1. public static void main(String[] args) throws IOException, ClassNotFoundException {
  2. //1. 创建流
  3. ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));
  4. //2. 读,必须按照序列化顺序读取且不可多读,否则引发EOFException异常。
  5. String s = (String)(ois.readObject();
  6. System.out.println(s);
  7. //3.关闭
  8. ois.close();
  9. }

细节: 1. 反序列化必须提供需要的字节码 2. 本地字节码版本号和流中的版本号要一致。

四、字符流

文件流[重点]

以子符形式读取文件数据,通常适用于读取纯文本文件 存文本信息。

FileReader 输入流

  1. /*
  2. * 需求:往文件中读数据
  3. * 写数据--输出流--FileReader
  4. */
  5. public class FileReaderDemo {
  6. public static void main(String[] args) throws IOException {
  7. //创建一个File类
  8. File f = new File("d:\\Test.txt");
  9. //创建输入流对象
  10. FileReader fr = new FileReader(f);
  11. //方式1:读数据
  12. int n = fr.read();
  13. while(n! = -1){
  14. System.out.print(n);
  15. n= fr.read();
  16. }
  17. //方式2:读数据
  18. int n;
  19. while((n=fr.read())!=-1) {
  20. System.out.print((char)n);
  21. }
  22. //关闭流
  23. fr.close();
  24. }
  25. }

FileWriter 输出流

  1. /*
  2. * 需求:往文件中写数据
  3. * 写数据--输出流--FileWriter
  4. */
  5. public class FileWriter {
  6. public static void main(String[] args) {
  7. //目标文件
  8. File f = new File("d:\\demo.txt");
  9. //创建输出流对象
  10. FileWriter fw = new FileWriter();
  11. //写数据
  12. String str = "你好中国";
  13. char[] chars = str.toCharArray();
  14. fw.write(chars);
  15. //关闭流
  16. fw.close();
  17. }
  18. }

利用:FileReader、FileWriter文件复制

  1. public class FileWriter {
  2. public static void main(String[] args) {
  3. //源文件
  4. File f1 = new File("d:\\demo.txt");
  5. //目标文件
  6. File f2 = new File("d:\\demo1.txt");
  7. //创建输入流对象
  8. FileReader fr = new FileReader(f1);
  9. //创建输出流对象
  10. FileWriter fw = new FileWriter(f2);
  11. //【方式1 读数据 写数据】
  12. int n = fr.read();
  13. while(n! = -1){
  14. fw.write(n)
  15. n= fr.read();
  16. }
  17. //【方式2 利用缓冲字符数组】
  18. char[] ch = new char[5];
  19. int len = fr.read(ch);
  20. while(len != -1){
  21. fw.write(ch,o,len)//将缓冲数组中有效长度写出
  22. len = fr.read(ch);
  23. }
  24. //关闭流(关闭流的时候,倒着关闭,后用先关)
  25. fw.close();
  26. fr.close();
  27. }
  28. }

注意事项
相对路径:相对当前项目而言的,在项目的根目录下(Test.txt)
绝对路径:以盘符开始的路径(d:\Test.txt)
* 不要用字符流操作非文本文件

close()和flush()方法的区别:

  • flush(): 刷新缓冲区。流对象还可以继续使用。
  • close(): 先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

    1. public class FileWriterDemo2 {
    2. public static void main(String[] args) throws IOException {
    3. //创建输出流对象
    4. //FileWriter fw = new FileWriter("d:\\word.txt");
    5. FileWriter fw = new FileWriter("word.txt");
    6. //调用输出流对象的写数据方法,并刷新缓冲区
    7. fw.write("helloworld");
    8. fw.flush();
    9. fw.write("java");
    10. fw.flush();
    11. //释放资源
    12. fw.close();
    13. //Stream closed
    14. //fw.write("javaee");
    15. //fw.flush();
    16. }
    17. }

构造方法

  • void write(String str):写一个字符串数据
  • void write(String str,int index,int len):写一个字符串中的一部分数据
  • void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。’a’,97
  • void write(char[] chs):写一个字符数组数据
  • void write(char[] chs,int index,int len):写一个字符数组的一部分数据

    1. public class FileWriterDemo3 {
    2. public static void main(String[] args) throws IOException {
    3. //创建输出流对象
    4. FileWriter fw = new FileWriter("b.txt");
    5. //void write(String str):写一个字符串数据
    6. //fw.write("abcde");
    7. //void write(String str,int index,int len):写一个字符串中的一部分数据
    8. //fw.write("abcde",0,5);
    9. //fw.write("abcde",1,3);
    10. //void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。'a',97
    11. //fw.write('a');
    12. //fw.write(97);
    13. //void write(char[] chs):写一个字符数组数据
    14. char[] chs = {'a','b','c','d','e'};
    15. //fw.write(chs);
    16. //void write(char[] chs,int index,int len):写一个字符数组的一部分数据
    17. //fw.write(chs,0,5);
    18. fw.write(chs,2,3);
    19. //释放资源
    20. fw.close();
    21. }
    22. }

缓冲流

BufferedReader 输入流

BufferedWriter 输出流

特别方法 **readLine() **可以一次读取一行,如果未读到返回null
特别方法 **newLine() **相当于写一个**换行**

  1. public static void main(String[] args) throws IOException {
  2. //1 创建流
  3. BufferedReader br = new BufferedReader( new FileReader("g:/book.txt"));
  4. //1 创建流
  5. BufferedWriter bw = new BufferedWriter( new FileWriter("node.txt",true));
  6. //2 读数据
  7. String str = br.readLine()//每次读取文本中一行,返回字符串
  8. while( str !=null ){
  9. br.write(str)
  10. bw.newLine();//换行
  11. str = br.readLine()
  12. }
  13. //3.关闭流
  14. bw.close();
  15. br.close();
  16. }

转换流

有些时候,如果读取的文件是文本文件,但是提供的却是字节流,字符流明显读取文本字符更加方便,这时可以把字节流转换成字符流操作。

只有字节流转 字符流没有字符流转字节流,转换流本身就是一种字符流。

InputStreamReader 输入流

  1. /**
  2. * 字节输入流 转 字符输入流
  3. */
  4. public class InputStreamReaderCase {
  5. public static void main(String[] args) throws IOException {
  6. //字符流
  7. BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream("d:/text.txt") ) );
  8. String buff = null;
  9. while ( (buff=br.readLine()) !=null ){
  10. System.out.println(buff);
  11. }
  12. br.close();
  13. }
  14. }

OutputStreamWriter 输出流

  1. *
  2. * 字节输出流 字符输出流
  3. */
  4. public class OutputStreamWriterCase {
  5. public static void main(String[] args) throws IOException {
  6. BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream("d:/text.txt") ) );
  7. bw.newLine();
  8. bw.write("王麻子,20,男,C#");
  9. bw.flush();
  10. bw.close();
  11. }
  12. }

利用:InputStreamReader、OutputStreamWriter文件复制

  1. public class Test {
  2. public static void main(String[] args) throws IOException {
  3. //源文件输入方向
  4. BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream("d:/text.txt") ) );
  5. //目标文件输出方向
  6. BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream("d:/text1.txt") ) );
  7. //开始动作
  8. char[] ch = new char[20];
  9. int len = br.read(ch);
  10. while(len!=-1){
  11. bw.write(ch,0,len)
  12. en = br.read(ch);
  13. }
  14. //关闭流
  15. bw.close();
  16. br.close();
  17. }
  18. }

编码与字符集

编码指的是把字符与数字对应的过程。 字符集就是一张记录了对应关系的信息表。ASCII就是一种编码表。像这种还有很多。

  1. GBK 国标码
  2. ISO-8859-1 西欧语言
  3. Big5 台湾香港 繁体字
  4. Unicode 联合编码( UTF-8 UTF-16 )

    1. public static void main(String[] args) throws IOException {
    2. String hello = "你好中国";
    3. byte[] bytes = hello.getBytes();// UTF-8 解码
    4. System.out.println(Arrays.toString(bytes));
    5. byte[] buff = {-28, -67, -96, -27, -91, -67, -28, -72, -83, -27, -101, -67};
    6. String newHello = new String( buff ,"UTF-8" ); // 使用 UTF-8 编码
    7. System.out.println(newHello);
    8. System.out.println("--------------------------------------");
    9. FileInputStream fis = new FileInputStream("d:/hello.txt");
    10. InputStreamReader isr = new InputStreamReader(fis,"GBK");
    11. char[] buff2= new char[1204];
    12. int len;
    13. while ( ( len = isr.read(buff2))!=-1 ){
    14. System.out.println(buff2);
    15. }
    16. isr.close();
    17. fis.close();
    18. }

    编码解码不一致,就会出现乱码

打印流

打印流也是输出流, 存在字节打印流和字符打印流。

字节打印流PrintStream

  1. public class PrintDemo {
  2. public static void main(String[] args) throws IOException {
  3. // 直接打印到文件
  4. PrintStream out = new PrintStream("d:/abc.txt");
  5. out.println("helloword");
  6. // 打印到 其他字节输出流
  7. FileOutputStream os = new FileOutputStream("d:/abc.txt",true);
  8. PrintStream out2 = new PrintStream( os);
  9. out2.println("java");
  10. }
  11. }

字符打印流 PrintWriter

  1. public class PrintDemo {
  2. public static void main(String[] args) throws IOException {
  3. //直接 打印到文件
  4. PrintWriter pw = new PrintWriter("D:/abc.txt");
  5. pw.println("css");
  6. pw.close();
  7. //打印 到其它字符输出流
  8. PrintWriter pw2 = new PrintWriter( new FileWriter("d:/abc.txt",true));
  9. pw2.println("java");
  10. pw2.close();
  11. //打印 到其他字节输出流
  12. PrintWriter pw2 = new PrintWriter( new FileOutputStream("d:/abc.txt",true) );
  13. pw2.println("java");
  14. pw2.close();
  15. }
  16. }

键盘录入的内容输出到文件中【重点】

  1. public class Test03 {
  2. public static void main(String[] args) throws IOException {
  3. // 1、先准备输入方向
  4. //键盘录入
  5. InputStream in = System.in;//属于字节流
  6. //字节流转字符流
  7. InputStreamReader isr = new InputStreamReader(in);
  8. //在isr外面套一个缓冲流
  9. BufferedReader br = new BufferedReader(isr);
  10. // 2、再准备输出方向
  11. //准备目标文件
  12. File f = new File("d:\\test.tex");
  13. FileWriter fw = new FileWriter(f);
  14. BufferedWriter bw = new BufferedWriter(fw);
  15. // 3、开始动作
  16. String s = br.readLine();
  17. while (!s.equals("exit")){
  18. bw.write(s);
  19. bw.newLine();
  20. s = br.readLine();
  21. }
  22. // 4、关闭流
  23. bw.close();
  24. br.close();
  25. }
  26. }

随机文件访问类

RandomAccessFile 此类是一个文件读写操作工具类,它和其他流不同,它没有方向性,它既可以读文件,也可以写文件。
支持模式: r 只读 w只写 rw读写
通过seek(int pos) 方法移动指针

  1. package print;
  2. import java.io.*;
  3. public class PrintDemo {
  4. public static void main(String[] args) throws IOException {
  5. //随机访问文件类
  6. RandomAccessFile raf = new RandomAccessFile("d:/abc.txt","rw");
  7. //移动光标到末尾 写数据
  8. raf.seek( raf.length() );
  9. raf.writeBytes("mysql");
  10. //移动光标到 开始 读操作
  11. raf.seek(0);
  12. String line = raf.readLine();
  13. System.out.println(line);
  14. raf.close();
  15. }
  16. }

System类对IO流的支持

**System.in**输入流——>默认情况下,从键盘输入
**Scanner**: 起扫描作用

  1. public class Test {
  2. public static void main(String[] args) throws IOException {
  3. Scanner sc = new Scanner(new FileInputStream(new File("d\\Test.txt")));
  4. while (sc.hasNext()){
  5. System.out.println(sc.next());
  6. }
  7. }
  8. }


**System.out**: 输出流——>默认情况下,输出到控制台

  1. public class Test02 {
  2. public static void main(String[] args) {
  3. //写到控制台
  4. PrintStream out = System.out;
  5. //调用方法:不换行
  6. out.print("你好1");
  7. out.print("你好2");
  8. out.print("你好3");
  9. //换行
  10. out.println("你好1");
  11. out.println("你好2");
  12. out.println("你好3");
  13. System.out.println("你是");
  14. System.out.print("中国人");
  15. }
  16. }