java io详解

目录

文件的编码

File类的使用

常用的API

遍历目录

RandomAccessFile

文件模型

打开方式

方法

IO流

字节流

InputStream(字节输入流)

常用方法

FileInputStream

OutputStream(字节输出流)

常用方法

FileOutputStream

字符流

Reader(字符输入流)

常用方法

示例

InputStreamReader

FileReader

Writer(字符输出流)

常用方法

示例

OutputStreamWriter

FileWriter

字符流与字节流的区别

字节缓冲流

字符缓冲流


文件的编码

public static void main(String[] args) throws UnsupportedEncodingException {

    String s = "慕课ABC";

    byte[] bytes1 = s.getBytes(); //把字符串转换成字符数组,转换成的字节序列用的是项目默认的编码GBK

    for(byte b : bytes1){

        //把字节(转换成了int)以16进制的方式显示

        //toHexString这个函数是把字节(转换成了Int)以16进制的方式显示

        System.out.println(Integer.toHexString(b & 0xff)+""); // & 0xff是为了把前面的24个0去掉只留下后八位

    }


    byte[] bytes2=s.getBytes("gbk");//也可以转换成指定的编码

    for(byte b : bytes2){

        //把字节(转换成了int)以16进制的方式显示

        //toHexString这个函数是把字节(转换成了Int)以16进制的方式显示

        System.out.println(Integer.toHexString(b & 0xff)+""); // & 0xff是为了把前面的24个0去掉只留下后八位

    }

}

gbk编码: 中文占用两个字节,英文占用一个字节

utf-8编码:中文占用三个字节,英文占用一个字节

java是双字节编码,是utf-16be编码

utf-16be编码:中文占用两个字节,英文占用两个字节

当你的字节序列是某种编码时,这个时候想把字节序列变成字符串,也需要用这种编码方式,否则会出现乱码

String str1=new String(bytes2);//这时会使用项目默认的编码来转换,可能出现乱码

要使用字节序列的编码来进行转换

String str2=new String(bytes2,"utf-16be");

文本文件就是字节序列,可以是任意编码的字节序列

如果我们在中文机器上直接创建文本文件,那么该文件只认识ANSI编码(例如直接在电脑中创建文本文件)

中文机器上创建的文本文件只能识别ansi编码

File类的使用

Java.IO.File类表示文件或目录,只用于表示文件或目录得信息,不能用于文件的访问。

常用的API

        1.创建File对象

File file=new File(String path);注意:File.seperater();获取系统分隔符,如:”\“.

        2.boolean file.exists();是否存在.

        3.file.mkdir();或者file.mkdirs();创建目录或多级目录。

        4.file.isDirectory()或者file.isFile()判断是否是目录或者是否是文件。

        5.file.delete();删除文件或目录。

        6.file.createNewFile();创建新文件。

        7.file.getName()获取文件名称或目录绝对路径。

        8.file.getAbsolutePath()获取绝对路径。

        9.file.getParent();获取父级绝对路径。

        10.file.getSize();获取文件大小。

        11.file.getFormat();获取文件格式名

遍历目录

//常用操作:过滤,目录....

public class FileUtils {

    /**
     * 列出指定目录下的所有文件
     *
     * @param dir
     * @throws IOException
     */

    public static void listDirectory(File dir) throws IOException {

//判断文件或目录是否存在

        if (!dir.exists()) {

            throw new IllegalArgumentException("目录:" + dir + "不存在。"); //抛出异常

        }

//判断File类的对象是否是目录

        if (!dir.isDirectory()) {

            throw new IllegalArgumentException(dir + "不是目录。"); //抛出异常

        }

//返回的是字符串数组,列出当前目录下的所有子目录和文件,不包含子目录下的内容

        String[] filenames = dir.list();

//将filenames数组中的值,循环赋值给string,直到filenames为空时,结束循环

        for (String s : filenames) {

            System.out.println(s);

        }
    }
}

如果要遍历目录下的内容就需要构造成File对象做递归操作,File提供了直接返回File对象的API:

File[] files = dir.listFiles(); //返回的是直接子目录(文件)的抽象

递归,遍历出该目录下所有文件信息,包括子目录下的文件

for(File f :files){

        if(f.isDirectory()){

                //递归遍历该目录下的子目录的信息

                listDirectory(dir);

        }else{

                System.out.println(dir);

        }

}

RandomAccessFile

RandomAccessFile:java提供的对文件内容的访问,既可以读文件,也可以写文件。支持随机访问文件,可以访问文件的任意位置。

文件模型

在硬盘上的文件时 byte byte byte存储的,是数据的集合

打开方式

1.rw:读写

2.r:只读

方法

raf.getFilePointer()获取当前指针位置 raf.length()获取文件长度 raf.seek()把指针指定到某一位置

raf.write(int) ----> 只写一个字节 (后8位) 同时指针指向下一个位置 准备再次写入

int b=raf.read(); 读一个字节

文件读写完成以后一定要关闭,否则会产生未知错误

IO流

IO即Input/Output,输入和输出。数据输入到计算机内存的过程叫输入;反正输出到外部设备(数据库、主机、文件)的过程叫输出。

数据传输的过程像水流。因此被称为IO流。

IO流在Java中被分为输入流和输出流,而根据数据的处理方式又分为字节流和字符流。

4大抽象类基类:

InputStream/Reader:所有的输入流的基类,前者是字节输入流,后者是字符输入流

OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流

字节流

字节流主要是操作byte类型数据,以byte数组为准,主要操作类时字节输入流InputStream、字节输出流OutputStream

InputStream(字节输入流)

InputStream:从文件中读取数据到内存中,java.io.InputStream抽象类是所有字节输入流的父类。

常用方法

        1.in.read():返回输入流中下一个字节的数据

        2.in.read(byte[] b):从输入流中读取一些字节存储到数组b中。如果数组b的长度为零,则不读取。如果没有可用字节读取,返回-1。如果有可用字节读取,则最多读取的字节数最多等于b.length

        3.in.read(byte[] buf,int start,int size):在read(byte b[ ]) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字节数)

        4.skip(long n):忽略输入流中的 n 个字节 ,返回实际忽略的字节数

        5.available():返回输入流中可以读取的字节数

        6.close():关闭输入流释放相关的系统资源

FileInputStream

FileInputStream是一个比较常用的字节输入流对象,可直接指定文件路径,可以直接读取单字节数据,也可以读取至字节数组中。

示例:

try (InputStream fis = new FileInputStream("input.txt")) {
    System.out.println("Number of remaining bytes:"
            + fis.available());
    int content;
    long skip = fis.skip(2);
    System.out.println("The actual number of bytes skipped:" + skip);
    System.out.print("The content read from file:");
    while ((content = fis.read()) != -1) {
        System.out.print((char) content);
    }
} catch (IOException e) {
    e.printStackTrace();
}

 文件内容:

结果输出:

Number of remaining bytes:11
The actual number of bytes skipped:2
The content read from file:JavaGuide

 般我们是不会直接单独使用 FileInputStream ,通常会配合 BufferedInputStream

// 新建一个 BufferedInputStream 对象
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("input.txt"));
// 读取文件的内容并复制到 String 对象中
String result = new String(bufferedInputStream.readAllBytes());
System.out.println(result);

OutputStream(字节输出流)

用于将数据(字节信息)写入到文件中,java.io.OutputStream抽象类是所有字节输出流的父类

常用方法

        writer(int b):将特定字节写入输出流

        writer(byte b[ ]):将数组b 写入到输出流

        writer(byte b[ ],int off,int len):在write(byte b[ ]) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字节数)

        flush():刷新此输出流并强制写出所有缓冲的输出字节

        close():关闭输出流释放相关的系统资源

FileOutputStream

是最常用的字节输出流对象,可直接指定文件路径,可以直接输出单字节数据,也可以输出指定的字节数组

示例:

try (FileOutputStream output = new FileOutputStream("output.txt")) {
    byte[] array = "JavaGuide".getBytes();
    output.write(array);
} catch (IOException e) {
    e.printStackTrace();
}

结果:

类似于 FileInputStreamFileOutputStream 通常也会配合 BufferedOutputStream(字节缓冲输出流)来使用。

FileOutputStream fileOutputStream = new FileOutputStream("output.txt");
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);

字符流

字符流:就是在字节流的基础上,加上编码,形成的数据流

意义:因为字节流在操作字符时,可能会有中文导致的乱码,所以由字节流引申出了字符流。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好

Reader(字符输入流)

Reader用于从源头(通常是文件)读取数据(字符信息)到内存中,java.io.Reader抽象类是所有字符输入流的父类

常用方法

        1.in.read():从输入流中读取一个字符

        2.in.read(char[] b):从输入流中读取一些字符,并将它们存储到字符数组 b中,等价于 read(b, 0, b.length)

        3.in.read(char[] buf,int off,int len):在read(char[] b) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字符数)

        4.skip(long n):忽略输入流中的 n 个字符 ,返回实际忽略的字符数

        5.close():关闭输入流并释放相关的系统资源

示例

// 1.使用File类找到一个文件

File f = new File("f:\\test.txt");

// 2.实例化输入流对象

Reader input = new FileReader(f);

// 3.读操作

char[] c = new char[1024];

int len = input.read(c);

// 4.关闭流

input.close();

System.out.println("文件内容:" + new String(c,0,len));

InputStreamReader

是字节流转换为字符流的桥梁,其子类 FileReader 是基于该基础上的封装,可以直接操作字符文件。

// 字节流转换为字符流的桥梁
public class InputStreamReader extends Reader {
}
// 用于读取字符文件
public class FileReader extends InputStreamReader {
}

FileReader

try (FileReader fileReader = new FileReader("input.txt");) {
    int content;
    long skip = fileReader.skip(3);
    System.out.println("The actual number of bytes skipped:" + skip);
    System.out.print("The content read from file:");
    while ((content = fileReader.read()) != -1) {
        System.out.print((char) content);
    }
} catch (IOException e) {
    e.printStackTrace();
}

文件内容:

输出:

The actual number of bytes skipped:3
The content read from file:我是Guide。

Writer(字符输出流)

常用方法

writer();

writer(char[ ]);

writer(char[ ],offset,len);

writer(string);

flush()刷新缓冲区

close()方法默认调用了flush()方法,但是flush()方法只刷新缓冲区,而close()还会关闭IO流

示例

//1.使用File类找到一个文件

File f = new File("f:\\test.txt");

//2.实例化输出流对象

Writer out = new FileWriter(f);

//3.写操作

String str = "Hello World!!";

out.write(str);

//4.关闭流

out.close();

OutputStreamWriter

是字符流转换为字节流的桥梁,其子类 FileWriter 是基于该基础上的封装,可以直接将字符写入到文件

// 字符流转换为字节流的桥梁
public class OutputStreamWriter extends Writer {
}
// 用于写入字符到文件
public class FileWriter extends OutputStreamWriter {
}

FileWriter

try (Writer output = new FileWriter("output.txt")) {
    output.write("你好,我是Guide。");
} catch (IOException e) {
    e.printStackTrace();
}

输出结果:

字符流与字节流的区别

1.字节流在操作的时候本身不用缓存区的,是与文件直接对接的;而字符流操作时需要缓冲区。

2.使用字节流时,即使流没有关闭,最终也可以输出到文件;

3.使用字符流时,所有的内容保存在缓冲区,流关闭时 会强制性的将缓冲区内容写到文件中,如果没有关闭流,文件中就不会有内容输出。

字节缓冲流

IO 操作是很消耗性能的,缓冲流将数据加载至缓冲区,一次性读取/写入多个字节,从而避免频繁的 IO 操作,提高流的传输效率。

字节缓冲流这里采用了装饰器模式来增强 InputStream 和OutputStream子类对象的功能。

字符缓冲流

        BufferedReader (字符缓冲输入流)和 BufferedWriter(字符缓冲输出流)类似于 BufferedInputStream(字节缓冲输入流)和BufferedOutputStream(字节缓冲输入流),内部都维护了一个字节数组作为缓冲区。不过,前者主要是用来操作字符信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值