JAVA IO流

1 File类

java.io.File类

  1. File新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。
  2. File对象可以作为参数传递给流的构造器
  3. File类实现了SerializableComparable<File>,说明它是支持序列化和排序的。
  4. 路径中的每级目录之间用一个路径分隔符隔开
    路径分隔符和系统有关:
    ● windows和DOS系统默认使用“\”来表示
    ● UNIX和URL使用“/”来表示
File file = new File("D:\\文件.txt");

1.1 常用构造器

方法名说明
File(File parent, String child)根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(String parent, String child)根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File(URI uri)通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例。

1.2 常用方法

方法说明
创建
createNewFile()当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
mkdir()创建此抽象路径名指定的目录。
mkdirs()创建此抽象路径名指定的目录包括任何必需但不存在的父目录
删除
delete()删除此抽象路径名表示的文件或目录。
重命名
renameTo(File dest)把文件重命名为指定的文件路径
判断
exists()测试此抽象路径名表示的文件或目录是否存在。
isDirectory()测试此抽象路径名表示的文件是否为目录
isFile()测试此抽象路径名表示的文件是否为普通文件
canRead()测试应用程序是否可以读取由此抽象路径名表示的文件。
canWrite()测试应用程序是否可以修改由此抽象路径名表示的文件。
isHidden()测试此抽象路径名表示的文件是否隐藏
获取
getAbsoluteFile()返回此抽象路径名的绝对路径名形式。
getAbsolutePath()返回此抽象路径名的绝对路径名字符串。
getName()获取名称
getPreant()获取上层文件目录路径
lastModifiled()返回最后一次修改的时间,毫秒值
list()返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。
list(FilenameFilter filter)返回一个字符串数组,命名由此抽象路径名表示的目录中满足指定过滤器的文件和目录。
listFile()返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。
length()返回由此抽象路径名表示的文件的长度。

File类使用实例

package file;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;

public class FileTest {
    public static void main(String[] args) throws IOException {
        File f = new File("FileTest");
        File file = new File("FileTest/FileTest.txt");
        File newName = new File("FileTest/newFile.txt");

        //判断目录是否存在
        System.out.println("文件是否存在: " + f.exists());
        //创建目录
        if (f.mkdir()) {
            System.out.println("文件创建成功!");
        }
        //判断文件是否存在
        System.out.println("文件是否存在: " + file.exists());
        //创建文件
        if (file.createNewFile()) {
            System.out.println("文件创建成功!");
        }

        //判断该文件是否是目录
        if (file.isDirectory()) {
            System.out.println("这是一个目录!");
        } else if (file.isFile()) {
            System.out.println("这是一个文件!");
        }
        //获取文件绝对路径
        System.out.println("文件的绝对路径是: " + file.getAbsolutePath());
        //获取上层文件目录路径
        System.out.println("上层目录路径为: " + file.getParent());

        //获取指定目录下以”.txt“结尾的文件
        File[] files = f.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                String fileName = name.toLowerCase(Locale.ROOT);
                return fileName.endsWith(".txt");
            }
        });
        //获取指定目录下的文件
        System.out.println("-------------------------------------");
        System.out.println("当前目录下所有文件为: ");
        String[] files1 = f.list();
        System.out.println(Arrays.toString(files1));

        System.out.println("获取所有.txt文件");
        for (File file1 :
                files) {
            System.out.println(file1);
        }

        System.out.println("----------------------------------------");


        //获取文件大小
        System.out.println("文件大小是: " + file.length());
        //修改文件名
        if (file.renameTo(newName)) {
            System.out.println("文件名修改成功");


            //获取文件名
            System.out.println("修改后文件名为: " + newName.getName());
        }
        //返回最后修改时间
        System.out.println("最后修改时间为: " + newName.lastModified());
        //删除文件
        if (newName.delete()) {
            System.out.println("删除成功");
        }
    }
}

2 IO流

2.1 字节流

InputStreamOutputStream是两个抽象类,是字节流的基类,所有具体的字节流实现类都是分别继承了这两个类。
InputStream

2.1.1 节点流

FileOutputSream

  1. 创建流对象,建立数据存放文件
    FileOutputStream fos = new FileOutStream(new File(“test.txt”))
    byte[] bs = {}
  2. 调用流对象的写入方法,将数据写入流
    fos.write(bs)
  3. 关闭流资源,并将流中的数据清空到文件中
    fos.close()
public class FileOutputStreamTest {
    public static void main(String[] args) throws IOException {
        // out.txt 不存在, 但是想写, 创建新文件
        // out.txt 存在, 将内容清空, 再写入 (从文件头开始写入)
        File file = new File("out.txt");
        // 打开流, 打开本地磁盘文件
        FileOutputStream fos = new FileOutputStream(file);

        // append-true, 打开文件, 并写入文件末尾 (追加)
        // FileOutputStream fos = new FileOutputStream(file, true);

        // 写入1个字节  0000 0000 0000 0000 0110 0000 0100 0000
        // fos.write(200);
        fos.write(-25);
        fos.write(-113);
        fos.write(-83);

        // 字节数组
        byte[] bs = {-25, -113, -83};
        // 将指定字节数组的所有字节一起写入文件中
        fos.write(bs);

        byte[] bs1 = "字符串编码".getBytes();
        // 将bs1字节中, 从off开始, 写len个字节
        fos.write(bs1, 3, 9);

        fos.close(); // 及时释放资源 - finally

    }

FileInputSream

  1. 建立一个流对象,将已存在的一个文件加载进流
    FileInputStream fis = new FileInStream(new File(“test.txt”))
  2. 创建一个临时存放数据的数组
    char[] ch = new char[1024];
  3. 调用流对象的读取方法将流中的数据读入到数组中
    fis.read(ch)
  4. 关闭资源
    fis.close()
public class FileInputStreamTest {
    public static void main(String[] args) throws IOException {
        // 如果文件不存在, 抛出 FileNotFoundException
        File file = new File("out.txt");

        FileInputStream fis = new FileInputStream(file);
        byte[] bs = new byte[(int)(file.length())];
        System.out.println("bs 的长度: " + bs.length);
        // 读一些字节, 存入到 bs 数组中
        int len = fis.read(bs);
        System.out.println(Arrays.toString(bs));
        System.out.println("读出来的个数: " + len);

        // 解码, 从bs数组的0位置开始, 一共解码 len 个字节
        String str = new String(bs, 0, len, "UTF-8");
        System.out.println("读出来的字节解码后: " + str);

        fis.close();
    }
}

  1. 在读取文件时,必须保证该文件已存在,否则报异常。
  2. 定义文件路径时,注意:可以用“/”或者“\”
  3. 在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文件将被覆盖

2.1.2 缓冲流

BufferedInputStream BufferedOutputStream
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区
缓冲区要在相应的节点流上

public class BufferedInputStreamTest {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("in.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        // 读一个字节, 存入到 int 类型的 i 中
        int i = bis.read();

        byte[] bs = new byte[10];
        // 读一些字节(最多10个), 存入到bs数组中, 并且实际读出来的字节个数是 len 个
        int len = bis.read(bs);

        FileOutputStream fos = new FileOutputStream("out.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        // 写一个字节
        bos.write(97);
        bos.write("hello".getBytes());
        bos.write("hello".getBytes(), 0, 2);

        bos.flush();
        bos.close();
    }
}

2.1.3 对象流

ObjectInputStream OjbectOutputSteam

  1. 序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
    反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
  2. 不能序列化static和transient修饰的成员变量
  3. 序列化
    某个类实现了 Serializable 接口
    创建一个 ObjectOutputStream
    调用 ObjectOutputStream 对象的 writeObject(对象) 方法输出可序列化对象
    注意写出一次,操作flush()一次
  4. 反序列化
    创建一个 ObjectInputStream
    调用 readObject() 方法读取流中的对象
public class Person implements Serializable {
    // 添加了版本号以后, 对象的类可以进行调整
    public static final long serialVersionUID = 2l;
    private int age;
    private String name;
    
}
        Person p1 = new Person(18, "狗蛋");
        p1.setSex('男');
        FileOutputStream fos = new FileOutputStream("obj.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        // 序列化
        oos.writeObject(p1);

        oos.close();
        FileInputStream fis = new FileInputStream("obj.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);

        // 反序列化
        Person p1 = (Person)ois.readObject();
        ois.close();

        System.out.println(p1);     

对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

  1. 序列化好处是可将任何实现了Serializable接口的对象转化为字节数据,使其保存和传输时可被还原
  2. 凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
    private static final long serialVersionUID;
  3. Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常

2.1.4 打印流

PrintStream

public class PrintDemo {
    public static void main(String[] args) throws IOException {
        // 调⽤系统的打印流,控制台直接输出97
        System.out.println(97);
        // 创建打印流,指定⽂件的名
        PrintStream ps = new PrintStream("ps.txt");
        // 设置系统的打印流流向,输出到ps.txt
        System.setOut(ps);
        // 调⽤系统的打印流,ps.txt中输出97
        System.out.println(97);
    }
}

2.2 字符流

当使⽤字节流读取⽂本⽂件时,可能会有⼀个⼩问题。就是遇到中⽂字符时,可能不会显示完整的字符,那是因为⼀个中⽂字符可能占⽤多个字节存储。所以 Java 提供⼀些字符流类,以字符为单位读写数据,专⻔⽤于处理⽂本⽂件。
与字节流类似,字符流也有两个抽象基类,分别是ReaderWriter。其他的字符流实现类都是继承了这两个类。

2.2.1 节点流

FileReader()
FileReader(File file) :创建⼀个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName) :创建⼀个新的 FileReader ,给定要读取的⽂件的名称。

public class FRRead {
    public static void main(String[] args) throws IOException {

        // 使⽤⽂件名称创建流对象
        FileReader fr = new FileReader("read.txt");
        
        //单字符读取
        // 定义变量,保存数据
        int b;
        // 循环读取
        while ((b = fr.read()) != -1) {
            System.out.println((char) b);
        }

        //字符数组读取
        // 定义变量,保存有效字符个数
        int len;
        // 定义字符数组,作为装字符数据的容器
        char[] cbuf = new char[2];
        // 循环读取
        while ((len = fr.read(cbuf)) != -1) {
            System.out.println(new String(cbuf));
        }
        
        // 关闭资源
        fr.close();
    }
}


FileWriter()
FileWriter(File file) :创建⼀个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName) :创建⼀个新的 FileWriter,给定要读取的⽂件的名称。

import java.io.*;

public class FWWriter {
    public static void main(String[] args) throws IOException {

        FileWriter fw = new FileWriter("fw.txt");
        // 写出数据
        fw.write(97); // 写出第1个字符
        fw.write('b'); // 写出第2个字符
        fw.write('C'); // 写出第3个字符
        fw.write(30000); // 写出第4个字符,中⽂编码表中30000对应⼀个汉字。

        // 字符串转换为字节数组
        char[] chars = "程序员".toCharArray();
        // 写出字符数组
        fw.write(chars); // 程序员
        // 写出从索引1开始,2个字符。索引1是'序',两个字符,也就是'序员'。
        fw.write(b, 2, 2); // 序员


        // 字符串
        String msg = "程序员";
        // 写出字符数组
        fw.write(msg); //程序员
        // 写出从索引1开始,2个字符。索引1是'序',两个字符,也就是'序员'。
        fw.write(msg, 2, 2); // 序员
        /*
         *【注意】关闭资源时,与FileOutputStream不同。
         * 如果不关闭,数据只是保存到缓冲区,并未保存到⽂件。
         */
        fw.close();
    }
}
 

2.2.2 缓冲流

特有方法
字符缓冲流的基本⽅法与普通字符流调用方式⼀致,不再阐述,我们来看它们具备的特有⽅法。
BufferedReader: public String readLine() :读一行文字。
BufferedWriter: public void newLine() :写一行分隔符,由系统属性定义符号。
readLine 方法演示,代码如下:

public class BufferedReaderDemo {
 public static void main(String[] args) throws IOException {
 // 创建流对象
 BufferedReader br = new BufferedReader(new FileReader("in.txt"));
 // 定义字符串,保存读取的⼀⾏⽂字
 String line = null;
 // 循环读取,读取到最后返回null
 while ((line = br.readLine()) != null) {
 System.out.print(line);
 System.out.println("------");
 }
 // 释放资源
 br.close();
 }
}

newLine 方法演示,代码如下:

public class BufferedWriterDemo throws IOException {
 public static void main(String[] args) throws IOException {
 // 创建流对象
 BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"));
 // 写出数据
 bw.write("Java");
 // 写出换⾏
 bw.newLine();
 bw.write("程序");
 bw.newLine();
 bw.write("员");
 bw.newLine();
 // 释放资源
 bw.close();
 }
}
输出效果:
Java
程序
员

2.2.3 打印流

PrintWriter

public class PrintWriter {
    // PrintWriter 8个构造方法
    public static void main(String[] args) throws IOException {
        // 1.1直接传递一个文件名: 使用默认字符集, 清空原文件, 不会自动刷新缓冲区
        PrintWriter pw1 = new PrintWriter("out.txt");
        // 1.2传递一个文件名 + 字符集: 使用指定字符集, 清空原文件, 不会自动刷新缓冲区
        PrintWriter pw2 = new PrintWriter("out.txt", "GBK");
        // 2传递一个文件对象(或者 + 字符集): 效果同 1
        // 3.1传递一个字节流: 使用默认字符集, 清空原文件, 不会自动刷新
        FileOutputStream fos3 = new FileOutputStream("out.txt");
        PrintWriter pw3 = new PrintWriter(fos3);
        // 3.2传递一个字节流+自动刷新: 使用默认字符集, 清空原文件, 会自动刷新(println)
        FileOutputStream fos4 = new FileOutputStream("out.txt");
        PrintWriter pw4 = new PrintWriter(fos4, true);
        // 3.3传递一个字节流: 使用默认字符集, 在原文件上追加
        FileOutputStream fos5 = new FileOutputStream("out.txt", true);
        PrintWriter pw5 = new PrintWriter(fos5, true);

        // 4.传递一个字符流(或者 + 自动刷新): 效果同3
        // 5.转换流(字符流Writer)  OutputStreamWriter
        FileOutputStream fos = new FileOutputStream("out.txt", true);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
        PrintWriter pw = new PrintWriter(osw, true);

        pw.println("你好, 今天吃了吗? 没吃呢还");

        //pw.flush();
    }
}

2.2.4 转换流

转换流提供了在字节流和字符流之间的转换
Java API提供了两个转换流:
InputStreamReader:将InputStream转换为Reader
OutputStreamWriter:将Writer转换为OutputStream

InputStreamReader

  1. 实现将字节的输入流按指定字符集转换为字符的输入流
  2. 构造器
    public InputStreamReader(InputStream in)
    public InputSreamReader(InputStream in,String charsetName)

OutputStreamWriter

  1. 实现将字符的输出流按指定字符集转换为字节的输出流
  2. 构造器
    public OutputStreamWriter(OutputStream out)
    public OutputSreamWriter(OutputStream out,String charsetName)
FileInputStream fis = new FileInputStream("in.txt");
FileOutputStream fos = new FileOutputStream("out.txt");

InputStreamReader isr = new InputStreamReader(fis, "GBK");
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");

BufferedReader br = new BufferedReader(isr);
BufferedWriter bw = new BufferedWriter(osw);

String str = null;
while ((str = br.readLine()) != null) {
	bw.write(str);
	bw.newLine();
	bw.flush();
}

bw.close();
br.close();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值