Java超详细知识点——I/O流(字节流和字符流)

news2024/9/22 23:26:34

File类:

Java API:java.io.File 类 是用来操作文件或文件夹的,无法用来读写

1.首先创建一下file的对象:

里面可以写相对路径或者绝对路径

 File file = new File("CCC.java");

也可以使用其他构造方法

//String path = "D:\\ch06";
//String fileName = "1.txt";
File file = new File(path);
或者
File file1 = new File(path,fileName);
File类常用方法:

只有file对象才能够使用下面这些方法,字符串是不可以的(例如path.exsit是错误的)

代码示例:

这里的 isDirectory() 也可以判断这个file是否存在,不存在也返回false

isFile()也同理

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

        String path = "D:\\ch06";
        String fileName = "1.txt";
        File file = new File(path);
        File file1 = new File(path,fileName);
        if (!file.exists()&&!file.isDirectory()){
            //没有就重新创建
            file.mkdirs();//加上s就是创建多级
            System.out.println("创建文件夹成功");
        }
        if (!file1.exists()&&!file1.isFile()){

            file1.createNewFile();
            System.out.println("创建成功");
        }


     
        System.out.println("判断文件或目录是否存在:"+file.exists());
        System.out.println("只有file对象才能使用exists方法"+file1.exists());
        System.out.println("判断是否是文件夹"+file.isFile());
        System.out.println("判断是否是目录"+file.isDirectory());

        System.out.println("file1的相对路径"+file1.getPath());
        System.out.println("file的相对路径"+file.getPath());
        System.out.println("它的绝对路径"+file.getAbsolutePath());
        System.out.println("获得文件或目录名称"+file.getName());
        System.out.println("获得文件字节数"+file.length());
        System.out.println("删除文件或目录"+file.delete());
    }

流:

java如何读写文件?:通过流

流是一组有序的数据序列以先进先出方式发送信息的通道

Java流的分类:

1.按照流向区分

输入流和输出流

对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

2.按照处理数据单元划分

字符流和字节流

字节流是8位通用字节流,字符流是16位Unicode字符流

字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:

(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。

结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。

字节流概述(InputStream和OutputStream):

InputStream被看成一个输入管道,OutputStream被看成一个输出管道,数据通过InputStream从源设备输入到程序,通过OutputStream从程序输出到目标设备,从而实现数据的传输。由此可见,I/O流中的输入/输出都是相对于程序而言的。

InputStream类(读取文件):

常用方法:

第一个read()方法是从输入流中逐个读入字节,而第二个和第三个read()方法则将若干字节以字节数组的形式一次性读入,从而提高读数据的效率。

方法

方法描述

int read( )

从输入流读取一个8位的字节,把它转换为0~255之间的整数,并返回这一整数。当没有可用字节时,将返回-1

int read(byte[] b)

装字节数组

从输入流读取若干字节,把它们保存到参数b指定的字节数组中,返回的整数表示读取字节的数目

int read(byte[] b,int off,int len)

从输入流读取若干字节,把它们保存到参数b指定的字节数组中,off指定字节数组开始保存数据的起始下标,len表示读取的字节数目

void close( )

关闭此输入流并释放与该流关联的所有系统资源

int available();

获取当前流中可用的字节数。

字节流读取文件内容:

问题1:为什么把默认的throw new RuntimeException(e);都变成e.printStackTrace():

答:

e.printStackTrace(); 如果你的主要目标是确保程序继续运行,并记录发生的异常

throw new RuntimeException(e); 如果你希望在资源清理过程中发生异常时,中断程序以确保异常得到处理。

问题2:

要确保记事本的编码和idea的编码一致传过来才不报错,不然会乱码,原因是:

如果你用 GBK 编码保存文件,而 IntelliJ IDEA 使用 UTF-8 解码,那么字节会被错误地解释成字符,导致显示为乱码。(GBK用两个字节表示一个中文和英文,UTF-8用三个字节表示中文一个自己表示英文)

步骤:

1.创建FileInputStream输入流文件对象

2.获得文件内容:is.available()获取的文件放在数组中

3.使用read方法读取字节数组

4.将字节数组转为字符串,通过String str = new String(b,"GBK"); 将字节数组转换为字符串可以使数据更具可读性。

  public static void main(String[] args) {
        //读取文件
        InputStream is = null;
        try {
            is = new FileInputStream("D:\\ch06/1.txt");
            byte b[] = new byte[is.available()];
            //available()可获得的文件字节数
            is.read(b);
            //将字节数组转为字符串
            String str = new String(b,"GBK");
            System.out.println(str);
        } catch (Exception e) {
             e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

子类FileInputStream常用的构造方法:

第一种:FileInputStream(File file)

File file1 = new File("D:\\ch06/1.txt");
InputStream is = new FileInputStream(file1);

第二种:FileInputStream(String name)

放String路径

String str1 = "D:\\ch06/1.txt";
InputStream is = new FileInputStream(str1);
InputStream is2 = new FileInputStream( "D:\\ch06/1.txt");

OutputStream类(写入文件):

常用方法:

第一个方法逐个写入字节,后两个方法是将若干个字节以字节数组的形式一次性写入,从而提高写数据的效率。

方法

描述

void write(int c)

向输出流写入一个字节

void write(byte[] buf)

放字节数组

把参数b指定的字节数组的所有字节写到输出流

void close()

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

void flush():

这个后面讲

强制把缓冲区的数据写到输出流中

字符串对象.getBytes()

String 对象转换为字节数组。

将字符串写入文件:

步骤:

1.首先创建OutputStream对象

2.写出要写入的字符串

3.使用getBytes()方法将字符串转为字节数组mag.getBytes()

3.使用write方法读取字符串 os.write(mag.getBytes());

 public static void main(String[] args) throws IOException {
        String str1 = "D:\\ch06/1.txt";
        OutputStream os = new FileOutputStream(str1,true);
        String mag = "蛋蛋怪嘎达嘎达";
        //将字符串转为字节数组
        //mag.getBytes()
        os.write(mag.getBytes());
        System.out.println("写入成功");
        os.close();
}
子类FileOutputStream常用的构造方法:

1.直接放文件

OutputStream os = new FileOutputStream( "D:\\ch06/1.txt");   

2.直接放路径字符串

String str1 = "D:\\ch06/1.txt";
OutputStream os = new FileOutputStream(str1);   

3.可以在后面追加

String str1 = "D:\\ch06/1.txt";
OutputStream os = new FileOutputStream(str1,true);    

1.前两种构造方法在向文件写数据时将覆盖文件中原有的内容,因为前两种默认append是false

2.创建FileOutputStream实例时,如果相应的文件并不存在,则会自动创建一个空的文件

FileInputStream和 FileOutputStream文件的拷贝:

while循环将字节逐个进行拷贝。每循环一次,就通过FileInputStream的read()方法读取一个字节,并通过FileOutputStream的write()方法将该字节写入指定文件,循环往复,直到读取的长度len的值为-1,表示读取到了文件的末尾,结束循环,完成文件的拷贝。

 public static void main(String[] args) throws Exception {
                    // 创建文件输入流对象读取指定目录下的文件
                    FileInputStream in = new FileInputStream("source/src.png");
                    // 创建文件输出流对象将读取到的文件内容写入到指定目录的文件中
                    FileOutputStream out = new FileOutputStream("target/dest.png");
                    // 定义一个int类型的变量len
                   int len = 0;
                    // 获取拷贝文件前的系统时间
                    long beginTime = System.currentTimeMillis();
                    // 通过循环将读取到的文件字节信息写入到新文件
                    while ((len = in.read()) != -1) {
                            out.write(len);
                        }
                    // 获取拷贝之后的系统时间
                    long endTime = System.currentTimeMillis();
                   // 输出拷贝花费时间
                    System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
                    // 关闭流
                    in.close();
                    out.close();
                }

字符流(Reader和Writer):

InputStream类和OutputStream类在读写文件时操作的都是字节,如果希望在程序中操作字符,使用这两个类就不太方便了

同字节流一样,字符流也有两个抽象的顶级父类,分别是Reader和Writer。其中Reader是字符输入流,用于从某个源设备读取字符。Writer是字符输出流,用于向某个目标设备写入字符。

其中FileReader和FileWriter用于读写文件,BufferedReader和BufferedWriter是具有缓冲功能的流,使用它们可以提高读写效率。

InputStramReader输入流(读取):

Reader——>InputStreamReader(字节流InputStream,编码)——>FileReader(路径||"编码")

InputStream——>FileInputStream

乱码问题:

因为FileInputStream是InputStream的子类,所以可以直接在InputStreamReader中new

 reader = new InputStreamReader(new FileInputStream("D:\\ch06/1.txt"),"utf-8");

读取只能读字符数组,输出只能输出字符串

所以读完数组之后,把数组转成字符串

1.使用InputStreamReader读取文件:
  public static void main(String[] args) {

        Reader reader = null;
        try {
            reader = new InputStreamReader(new FileInputStream("D:\\ch06/1.txt"));//这里面也可以放file对象);
            char c[] = new char[100];
            //因为这个时候无法确定读取长度,就随便设一个长度
            reader.read(c);
            String msg = new String(c);
            System.out.println(msg);
            reader. close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

2.使用FileReader读取文件:
   public static void main(String[] args) {
       try {
           Reader reader = null;
           reader =   new FileReader("D:\\ch06/1.txt");

           char c[] = new char[100];
           reader.read(c);
           //把字符数组转为字符串
           String msg = new String(c);
           System.out.println(msg);


       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }


   }

BufferReader缓冲区读取数据:

因为使用read()方法会频繁读取输入流,压力太大了,所以用缓冲区来减小压力

子类BufferedReader特有的方法:

我们可以用BufferReader的.readLine()方法用来读取一行

public static void main(String[] args) {
        Reader reader = null;
        BufferedReader br = null;
        try {
            reader = new InputStreamReader(new FileInputStream("D:\\ch06/1.txt"));
            br = new BufferedReader(reader);
            String msg = null;
            
            while ((msg = br.readLine())!=null){
                System.out.println(msg);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

输出流OutputStramReader(写入):

Writer——>OutputStreamWriter(字节流OutputStream,编码)——>FileWriter(路径||File对象,append)

OutputStream——>FileOutputStream

weite(字符串) 写入方法

close() 释放资源

flush() 刷新缓冲区

直接write方法就写进去了,不需要什么数组

1.使用FileWriter写入文本:

  public static void main(String[] args) {
        //输出流
        Writer writer = null;
        try {
            writer = new FileWriter("D:\\ch06/1.txt",true);
            //写入
            writer.write("我是新写入的内容,不覆盖你好蛋蛋怪");

        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            writer.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

2.使用OutputStreamWriter写入文本:

public static void main(String[] args) {
        //OutputStreamWriter写
        Writer writer = null;
        try { 
            writer = new OutputStreamWriter(new FileOutputStream("D:\\ch06/1.txt"),"utf-8");
            writer.write("你好蛋蛋怪");
       
        } catch (Exception e) {
           e.printStackTrace();
        }finally {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

BufferWriter缓冲区读取数据:

减少直接对磁盘的写入次数,从而提升性能。写入的数据首先被存储在缓冲区中,只有当缓冲区满了或者调用了 flush() 方法时,数据才会实际写入文件。

子类BufferedWriter的方法:

flush(); 强制将缓冲区中的所有数据写入到目标流或文件中

bw.newLine();换行

  public static void main(String[] args) {
        Writer writer = null;
        BufferedWriter bw = null;
        try {
            writer = new FileWriter("D:\\ch06/1.txt");
            bw = new BufferedWriter(writer);

            bw.write("嘎嘎小啾啾");
            bw.newLine();
            bw.write("鳞斑响尾蛇");
            bw.newLine();
            bw.write("啾啾小啾啾");
            //强制将缓冲区中的所有数据写入到目标流或文件中
            bw.flush();
            System.out.println("写入成功");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                bw.close();
                writer.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2122416.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机网络】电路交换、报文交换和分组交换——三种交换方式性能分析以及计算机网络的分类

【计算机网络】电路交换、电报交换、分组交换 目录 【计算机网络】电路交换、电报交换、分组交换1. 电路交换2. 电报交换3. 分组交换4. 基于分组交换~“虚电路交换”技术 【计算机网络】电路交换、报文交换和分组交换——三种交换方式性能分析电路交换性能分析报文交换性能分析…

在AD域中恢复被删除的账户(LDP.EXE)

在域账户被不小心删除后,客户端使用域账号登陆会失败,账号不存在; 为了客户端登陆回原来账户文件下面,重新创建一个相同账户,域中此新账号的ID是新的,客户端登陆也会按新用户生成用户文件;同样复…

只用一个 HTML 元素可以写出多少形状?——动画篇

为期一个多月,我们针对只用一个 div 元素一共可以写出多少种形状的话题,通过六个篇章(分了八篇文章)进行了详细的展开。 其中,前三个篇章,我们主要围绕欧几里得几何中的基本形状做的展开,其中蕴…

基于Matlab和OpenCV的双目测距(标定和代码教程)

基于Matlab和OpenCV的双目测距研究 *摘要*:双目测距的原理是利用左右两个摄像机拍摄同一物体形成的视差来确定物体距摄像机的距离。这其中需要通过标定得出的参数包括内参(焦距fc, 主点Principal point, 径向畸变Radial Distortion, 切向畸变Tangential…

828华为云征文 | 使用Flexus云服务器X实例部署Kubernetes图形化管理平台

828华为云征文 | 使用Flexus云服务器X实例部署Kubernetes图形化管理平台 1. 基础部署环境说明2. 部署Kubernetes环境3. 部署Kubernetes Dashboard4. 创建登录账号token5. 访问Kubernetes Dashboard 1. 基础部署环境说明 Kubernetes作为当今最流行的容器编排平台,随着…

【Kubernetes】常见面试题汇总(七)

目录 20.简述 Kubernetes 创建一个 Pod 的主要流程? 21.简述 Kubernetes 中 Pod 的重启策略? 20.简述 Kubernetes 创建一个 Pod 的主要流程? Kubernetes 中创建一个 Pod 涉及多个组件之间联动,主要流程如下: &#…

如何让Google收录我的网站?

其实仅仅只是收录,只要在GSC提交网址,等个两三天,一般就能收录,但收录是否会掉,这篇内容收录了是否有展现,排名,就是另外一个课题了,如果不收录,除了说明你的网站有问题&…

人工智能赋能千行百业

人工智能将赋能千行百业 人工智能(AI)作为当今科技领域的核心驱动力之一,正以前所未有的速度和广度赋能千行百业,深刻改变着我们的生产、生活方式以及社会经济的运行模式。以下是人工智能在多个行业中的赋能作用的几个关键方面&am…

QT多个界面

主函数 #include "widget.h" #include "second.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;Second s;QObject::connect(&w,&Widget::my_signals,&s,&Second::my_slots);w.…

全面质量管理知识竞赛题库

全面质量管理知识竞赛题库 第 1 章 质量 三、单项选择题 1.根据 ISO9000 标准的定义&#xff0c;“质量”是指“客体的一组固有特性满足要求的程度”&#xff0c;以下&#xff08; B &#xff09;不属于产 品的“固有特性”。 A.产品的寿命 B.产品的价格 C.产品制造和使用的…

民宿|基于java的民宿推荐系统(源码+数据库+文档)

民宿推荐系统 目录 基于java的民宿推荐系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 前台&#xff1a; 后台&#xff1a; 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌…

react-问卷星项目(1)

学习的一位MOOC老师的经验&#xff0c;记录一下学习的过程 本项目技术栈&#xff1a;React18TS4AntDesign5Next.js13 项目&#xff1a;低代码&#xff0c;B/C react官方文档 核心价值&#xff1a; 组件化&#xff1a;不是React原创&#xff0c;但在React中流行开来 数据驱…

怎么用python打开文件

python文件读写文件是最常见的IO操作。Python内置了读写文件的函数&#xff0c;用法和C是兼容的。 读写文件前&#xff0c;我们先必须了解一下&#xff0c;在磁盘上读写文件的功能都是由操作系统提供的&#xff0c;现代操作系统不允许普通的程序直接操作磁盘。 读写文件就是请…

使用java对栅格数据的处理,对栅格文件进行导入导出

需求背景&#xff1a; 对栅格文件进行导入导出&#xff08;使用代码的方式&#xff0c;非命令方式&#xff09;&#xff1b; 当然也可以使用代码和GDAL的方式进行&#xff0c;但是GDAL配置部署不便捷&#xff0c;故选用GeoTools方式来实现。 ps&#xff1a;若是使用命令方式&am…

大模型api谁家更便宜

1 openai 可点此链接查询价格&#xff1a;https://openai.com/api/pricing/ 2 百度 可点此链接查询价格&#xff1a;https://console.bce.baidu.com/qianfan/chargemanage/list 需要注意&#xff0c;百度千帆平台上还提供其他家的模型调用服务&#xff0c; 如llama, yi-34b等…

IDE快速复制文件名

在很多情况下我们需要复制IDE中文件的名称&#xff0c;习惯性的F2却不能重命名 如图操作又比较繁琐 解决方法⭐⭐⭐ 其实直接CtrlC可以复制文件名&#x1f921;&#x1f921;&#x1f921;

7-Zip压缩包如何添加密码,加密后如何取消

压缩包文件大家经常使用&#xff0c;最熟悉的肯定是RAR、ZIP格式压缩文件&#xff0c;但是7z压缩文件格式也很好用&#xff0c;它是三种压缩文件格式中压缩率最大的。想要将文件压缩到最小&#xff0c;使用7z格式可以达到最大化。那么在使用7z压缩格式的时候&#xff0c;我们可…

银河麒麟V10系统软件商店手动更新方法

银河麒麟桌面操作系统V10重新安装之后&#xff0c;有些软件商店未能及时的自动更新&#xff0c;从而软件商店里无法获取最新的软件应用&#xff0c;这个时候就需要我们手动的进行升级更新一下软件商店了&#xff0c;更新之后软件商店里的内容就会增加不少&#xff0c;那么&…

阿尔泰科技案例解析-炼钢厂设备监测解决方案!

案例背景 在一家大型钢铁冶炼厂中&#xff0c;熔炉是生产过程的核心设备&#xff0c;广泛应用于金属冶炼、铸造和加工步骤&#xff0c;如钢铁的冶炼和精炼。为了确保熔炉在最佳状态下运行&#xff0c;并防止潜在的故障或事故&#xff0c;该厂需要对熔炉及厂房内相关设备的多个…

开发模型例题

答案&#xff1a;A 解析&#xff1a;瀑布模型是跟对需求明确的项目 增量模型是将需求分为多个阶段&#xff0c;适合一开始需求不明确的 演化模型适合用户需求不清&#xff0c;需求经常变化的情况 螺旋模型适合庞大&#xff0c;复杂且具有高风险的系统