四、文件传输基础——Java IO流

1、文件的编码(Java是双字符编码UTF-16be编码)

  • GBK编码中文占2个字节,英文占1个字节。
  • UTF-8编码中文占3个字节,英文占1个字节。
  • UTF-16be中文占2个字节,英文占2个字节。

2、 File 类常用 API 介绍

  • file.exists():判断文件/文件夹是否存在。
  • file.mkdir():创建文件夹。
  • file.mkdirs():创建文件夹(多级目录)。
  • file.delete():删除文件/文件夹。
  • File.separator:设置分隔符。
  • file.isDirectory():是否是一个目录。
  • file.isFile():是否是一个文件。
  • file.createNewFile():创建文件。
  • file.getParent():获取父目录。
  • file.list():列出当前目录下的子目录和文件。

3、遍历目录

public class FileUtils {

    /**
     * 列出指定目录下(包括其子目录)的所有文件
     * @param dir
     * @throws IOException
     */
    public static void listDirectory(File dir) throws IOException {
        if (!dir.exists()) {
            throw new IllegalArgumentException("目录" + dir + "不存在.");
        }
        if (!dir.isDirectory()) {
            throw new IllegalArgumentException(dir + "不是目录.");
        }

        // 返回的是,直接子目录(文件)的抽象
        File[] files = dir.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 递归
                    listDirectory(file);
                } else {
                    System.out.println(file);
                }
            }
        }
    }

}

4、RandomAccessFile基本操作

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

5、字节流之文件输入流FileInputStream

  • InputStream抽象了应用程序读取数据的方式。
  • EOF = End 读到-1就是读到结尾。
  • in.read() 读取一个字节无符号填充到int低八位。-1是EOF。
  • in.read(byte[] buf) 读取数据填充到字节数组buf。
  • in.read(byte[] buf,int start,int size) 读取数据到字节数组buf,从buf的start位置开始,存放size长度的数据。
public class IOUtils {

    /**
     * 读取指定文件内容,按照16进制输出到控制台
     * 并且每输出10个byte换行
     * @param fileName
     * @throws IOException 
     */
    public static void printHex(String fileName) throws IOException {
        // 把文件作为字节流进行读操作
        FileInputStream in = new FileInputStream(fileName);
        int b;
        int i = 1;
        while ((b = in.read()) != -1) {
            if (b <= 0xf) {
                // 单位数前面补0
                System.out.println("0");
            }
            System.out.print(Integer.toHexString(b) + "  ");
            if (i++ % 10 == 0) {
                System.out.println();
            }
        }
        in.close();
    }
    
    public static void printHexByByteArray(String fileName) throws IOException {
        FileInputStream in = new FileInputStream(fileName);
        byte[] buf = new byte[2 * 1024];

        /**
         * 从in中批量读取字节,放到buf这个字节数组中,
         * 从第0个位置开始放,最多放buf.length个,
         * 返回的是读到的字节个数
         */
        int bytes = 0;// 一次性读完,说明字节数组足够大
        int j = 1;
        while ((bytes = in.read(buf, 0, buf.length)) != -1) {
            for (int i = 0; i < bytes; i++) {
                if (buf[i] <= 0xf) {
                    System.out.println("0");
                }
                System.out.print(Integer.toHexString(buf[i] & 0xff) + "  ");
                if (j++ % 10 == 0) {
                    System.out.println();
                }
            }
        }
        in.close();
    }

}

6、字节流之文件输出流FileOutputStream

  • OutputStream抽象了应用程序写出数据的方式。
  • out.write(int b) 写出一个byte到流,b的低8位。
  • out.write(byte[] buf) 将buf字节数组写入到流。
  • out.write(byte[] buf,int start,int size)。
public static void copyFile(File srcFile, File destFile) throws IOException {
    if (!srcFile.exists()) {
        throw new IllegalArgumentException("文件" + srcFile + "不存在.");
    }
    if (!destFile.isFile()) {
        throw new IllegalArgumentException(destFile + "不是文件.");
    }

    FileInputStream in = new FileInputStream(srcFile);
    FileOutputStream out = new FileOutputStream(destFile);
    byte[] buf = new byte[8 * 1024];
    int b;
    while ((b = in.read(buf, 0, buf.length)) != -1) {
        out.write(buf, 0, b);
        out.flush();
    }
    in.close();
    out.close();
}

7、 字节流之数据输入输出流

  • DataOutputStream/DataInputStream对“流”功能的扩展,可以更加方便的读取int、long,字符等类型数据。
  • DataOutputStream writerInt()/writeDouble()/writeUTF()都是以装饰模式实现的。
public static void main(String[] args) throws IOException {
    String file = "demo/test.txt";
    DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
    dos.writeInt(10);
    dos.writeInt(-10);
    dos.writeLong(10L);
    dos.writeDouble(10.12D);
    // 采用UTF-8编码写出
    dos.writeUTF("中国");
    // 采用UTF-16be编码写出
    dos.writeChars("Java");
    dos.close();
}

8、字节缓冲流

  • BufferedInputStream&BufferedOutStream 这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了IO的性能
/**
* 进行文件的拷贝,利用带缓冲的字节流
* @param srcFile
* @param destFile
* @throws IOException
*/
public static void copyFileByBuffer(File srcFile, File destFile) throws IOException {
    if (!srcFile.exists()) {
        throw new IllegalArgumentException("文件" + srcFile + "不存在.");
    }
    if (!destFile.isFile()) {
        throw new IllegalArgumentException(destFile + "不是文件.");
    }

    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));

    int c;
    while ((c = bis.read()) != -1) {
        bos.write(c);
        bos.flush();// 刷新缓冲区
    }
    bis.close();
    bos.close();
}

9、字节字符转换流

  • 认识文本和文本文件
    • Java的文本是(char)是16位无符号整数,是字符的unicode编码(双字节编码)
    • 文件是byte byte byte ...的数据序列
    • 文本文件是文本(char)序列,按照某种编码方案(UTF-8、UTF-16be、GBK)序列化为byte的存储结果
  • 字符流(Reader、Writer)
    • 字符的处理,一次处理一个字符
    • 字符的底层仍然是基本的字节序列
  • InputStreamReader 完成byte流解析为char流,按照编码解析
  • OutputStreamWriter 提供char流到byte流,按照编码解析
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 五、IO流 1、IO流概述 (1)用来处理设备(硬盘,控制台,内存)间的数据。(2)java中对数据的操作都是通过...
    佘大将军阅读 3,505评论 0 0
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 7,059评论 0 4
  • 文件的编码 java.io.File类用于表示文件(目录)File类只用于表示文件(目录)的信息(名称、大小等),...
    Hey_Shaw阅读 2,224评论 0 0
  • 1 IONo18 1.1IO框架 【 IO:Input Output 在程序运行的过程中,可能需要对一些设备进...
    征程_Journey阅读 4,522评论 0 1
  • 热播剧《都挺好》播完了,大结局是老大苏明哲回美国和老婆孩子过日子了,老二苏明成悔过自新,去非洲工作了,而明玉却放弃...
    瑾夏之絮阅读 1,560评论 0 0