【疯狂Java讲义】Java学习记录(IO流)

IO流

IO:Input / Output

完成输入 / 输出

应用程序运行时——数据在内存中                        ←→                把数据写入硬盘(磁带)

                                内存中的数据不可持久保存

输入:从外部存储器(硬盘、磁带、U盘)把数据读入内存中。

输出:从内存中把数据写入外部存储器(硬盘、磁带、U盘)中,这样就可以保证,即使程序退出了,数据依然不会丢失。

File —— 代表磁盘上的文件或目录

listRoot:列出磁盘上所有的根目录

exists:判断是否存在

mkdir:创建目录

listFiles():列出当前目录下所有的文件和子目录

listFiles(FileFilter filter):列出当前目录下符合指定条件的文件和子目录

listFiles(FilenameFilter filter)

列出某个磁盘所有的文件——递归

import java.io.File;public class ListE {public static void main(String[] args) {// 创建一个File,它代表了E盘File e = new File("e:/Program Files");List(e);}public static void List(File dir) {System.out.println(dir + "目录下包含的文件和子目录有:");// 该方法返回当前目录所包含的所有文件和子目录File[] files = dir.listFiles();for (File file : files) {System.out.println("	" + file);// 如果file是目录,继续列出该目录下所有文件if (file.isDirectory()) {List(file);}}}
}

 列出某个磁盘所有的.txt文件——递归

import java.io.*;public class FileFilterTest {public static void main(String[] args) {File e = new File("e:/");// 返回当前目录所包含的所有*.txt文件,此时就需要对文件进行过滤File[] files = e.listFiles(new FileFilter() {// pathname就代表正在处理的文件,如果该方法返回true,意味着该文件就被保留,否则该方法将会被过滤掉@Override// 没有比IOExcepiton更小的,所以只能用try catchpublic boolean accept(File pathname) {// 说明文件名以.txt结尾try {if (pathname.getCanonicalPath().endsWith("txt")) {return true;}} catch (IOException e) {e.printStackTrace();}return false;}});for (File file : files) {System.out.println(file);}}
}

File的特征:只能访问磁盘上的文件和目录,它无法访问文件内容。

如果要访问文件的内容,必须使用IO流

流的分类

1、按流的方向来分(从程序所在内存的角度来看)

(1)输入流

把外部输入读入当前程序所在内存

(2)输出流

把当前程序所在内存的数据输出到外部

2、按流处理的数据来分

(1)字节流

处理数据单位是字节(8bit),适应性广、功能强大

(2)字符流

处理的数据单元是字符。通常来说它主要用于处理文本文件

在处理文本文件时,比字节流方便

3、按流的角色来分

(1)节点流

直接和一个IO的物理节点(磁盘上的文件、网络)关联

(2)包装流(处理流 / 过滤流)

以节点为基础,包装之后得到的流

都继承了FilterXxx等基类

流的概念模型

输入流中的数据单元放入应用程序;应用程序中的数据单元放入输出流。

缓冲流

外部存储器的速度比内存的速度慢,外部存储器的读写与内存的读写并不同步

——通过缓冲就可以解决这种不同步

反正你把流用完了,

- 别忘记调用flush方法(把缓冲中的内容刷入实际的节点)

             调用close()也可——系统会在关闭之前,自动刷缓冲

IO流一共涉及40多个类

字节流字符流
节点流InputStreamOutputStreamReaderWriter抽象
FileInputStreamFileOutputStreamFileReaderFileWriter访问文件
ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter数组
PipedInputStreamPipedOutputStreamPipedReaderPipedWriter访问管道
StringReaderStringWriter访问字符串
缓冲流BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter缓冲
FilterInputStreamFilterOutputStreamFilterReaderFilterWriter抽象
PrintStreamPrintWriter打印
InputStreamReaderOutputStreamWriter转换
DataInputStreamDataOutputStream特殊

所有以InputStream结尾的都是字节输入流

所有以OutputStream结尾的都是字节输出流

所有以Reader结尾的都是字符输入流

所有以Writer结尾的都是字符输出流

1、FileInputStream 

import java.io.*;
public class FileInputStreamTest {public static void main(String[] args) throws IOException {// 创建输入流,相当于得到一根有水的水管FileInputStream fis = new FileInputStream("D:\\Program Files\\eclipse-java-2023-06-R-win32-x86_64\\workplace\\day\\src\\day13\\FileInputStreamTest.java");// System.out.print((char)fis.read());// 该方法每次只读一个字节/** 为了把fis中水滴全部“取出”内存,有两个做法:* 1、用大桶* 2、用循环*/byte[] buff = new byte[64]; // 我的水桶可以装64个“水滴”int hasRead = -1;//hasRead = fis.read(buff);// 用“桶”从fis(水管)中取水while((hasRead = fis.read(buff)) > 0) {// 上一次读取了几个字节,此处就输出几个字节System.out.println(new String(buff, 0 ,hasRead));}}
}

运行结果: 

 2、FileOutputStream

import java.io.FileOutputStream;
import java.io.IOException;public class FileOutputStreamTest {public static void main(String[] args) {FileOutputStream fos = null;try {// 得到输出流,相当于得到一个没有水滴的水管fos = new FileOutputStream("abc.txt");fos.write(97); // 每次输出"一个字节“fos.write(98);fos.write(99);fos.write(100);fos.write(101);fos.write("自由、民主的普世价值观~".getBytes());} catch (IOException ex) {ex.printStackTrace();} finally {try {fos.close();} catch (Exception ex) {ex.printStackTrace();}}

运行结果: 

复制文本文件

import java.io.*;
public class CopyTest {public static void main(String[] args) {// JDK 7提供了自动关闭资源的try语句try (// 创建输入流,得到一个有水滴的水管FileInputStream fis = new FileInputStream("D:\\Program Files\\eclipse-java-2023-06-R-win32-x86_64\\workplace\\day\\src\\day13\\CopyTest.java");// 创建输出流,得到一个空水管FileOutputStream fos = new FileOutputStream("D:\\Program Files\\eclipse-java-2023-06-R-win32-x86_64\\workplace\\day\\src\\day13\\test.txt"); ){int hasRead = -1;byte[] buff = new byte[128];// 从fis里读取水滴,放入buff中while((hasRead = fis.read(buff)) > 0) {// 将buff中水滴写入fos,hasRead用于控制:读了多少,就写多少fos.write(buff, 0, hasRead);}} catch (IOException ex) {ex.printStackTrace();}}
}

运行结果: 

节点流直接与IO节点关联

——IO节点有很多:键盘、网络、文件、磁带……

过滤流:建立在节点流的基础之上

        过滤流的好处:

        ——消除底层节点之间的差异

        ——使用过滤流的方法执行IO更加便捷

                FileOutputStream →PrintStream

                              FileWriter→PrintWriter

                         如果已经知道要读的内容是字符内容,就可按如下方式转换:

                         InputStream→InputStreamReader→BufferedReader

1、 FileOutputStream →PrintStream

import java.io.*;public class PrintStreamTest {public static void main(String[] args) {try (// 创建节点流,节点流使用不方便FileOutputStream fos = new FileOutputStream("D:\\Program Files\\eclipse-java-2023-06-R-win32-x86_64\\workplace\\day\\src\\day13\\my.txt"); // 把节点流包装成过滤流:消除节点流的差异,而且PrintStream的方法更加方便PrintStream ps = new PrintStream(fos);		){ps.println("我想");ps.println("我想早");ps.println("我想早点");} catch (Exception ex) {ex.printStackTrace();} }
}

运行结果: 

3、DataInputStream与DataOutputStream

它们是两个特殊的流——它们是过滤流(建立在已有IO的基础之上)

——它们只要增加一些特定的方法来读取特定的数据。

import java.io.*;
public class DataOutputStreamTest {public static void main(String[] args) {try (// 创建节点流——与磁盘上的文件关联FileOutputStream fos = new FileOutputStream("price.txt");// 创建过滤流,过滤流建立在节点流的基础上DataOutputStream dos = new DataOutputStream(fos);){dos.writeDouble(3.4);dos.writeDouble(5.23);dos.writeDouble(4.34);dos.writeDouble(5.12);} catch (Exception ex) {ex.printStackTrace();}	}
}

运行结果:

import java.io.*;
public class DataInputStreamTest {public static void main(String[] args) {try (// 先创建节点流,与指定物理节点(文件)建立读写FileInputStream fis = new FileInputStream("price.txt");// 以节点流来创建过滤流DataInputStream dis = new DataInputStream(fis);){System.out.println(dis.readDouble());System.out.println(dis.readDouble());System.out.println(dis.readDouble());} catch (Exception ex) {ex.printStackTrace();}}
}

运行结果:

重定向标准输入输出

System.in——标准输入。通常代表键盘。

System.out——标准输出。通常代表屏幕。

System.setOut() ——可以将标准输出重定向另一个输出流。

import java.io.*;
public class SetOutTest {public static void main(String[] args) throws Exception{// 可以将标准输出重定向到指定的输出流System.setOut(new PrintStream("out.txt"));System.out.println("ABC");System.out.println("ABC");System.out.println("ABC");System.out.println("ABC");}
}

运行结果:输出的内容重定向到out.txt文本文件中 

System.setIn() ——可以将标准输出重定向另一个输入流。

import java.io.*;
public class RedirectKeyIn {public static void main(String[] args) throws Exception {// 将标准输入重定向到RedirectKeyIn.javaSystem.setIn(new FileInputStream("RedirectKeyIn.java"));//System.in,它是一个节点流,一般关联着物理键盘//直接用System.In(InputStream——节点、字节、输入流)可以读取键盘输入//缺点是:太繁琐、而且效率相当低下//System.out.println(System.in.read());InputStreamReader reader = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(reader);String line = null;// 控制BufferedReader每次读取一行while ((line = br.readLine()) != null) {System.out.println(line);}}
}

运行结果:

Java虚拟机读取其他进程的数据 

Java如何启动其他进程:Runtime实例.exec()

该方法的返回值是一个Process对象

Process——代表一个进程。

                    进程就是运行中的应用程序。

import java.io.*;
public class ReadFromProcess {public static void main(String[] args) throws Exception{Runtime runtime = Runtime.getRuntime();// 启动javac应用程序,返回该应用程序对应的进程
//		Process proc = runtime.exec("javac.exe -encoding UTF8 -d . ReadFromProcess.java");Process proc = runtime.exec("javac.exe -encoding UTF8 -d . ReadFromProcess");// 要得到javac应用程序输出的内容,此处应该用输入流?还是输出流?// 对于javac来说,是输出;但对于我们应用程序来说,用输入流InputStreamReader reader = new InputStreamReader(proc.getErrorStream());BufferedReader br = new BufferedReader(reader);String line = null;StringBuilder sb = new StringBuilder();// 控制BufferedReader每次读取一行while ((line = br.readLine()) != null) {//System.out.println(line);sb.append(line);}// 如果有错误输出if (sb.toString().length() > 0) {System.out.println("编译出错,错误信息如下----");// 输出错误提示System.out.println(sb);} else {System.out.println("成功完成----");}}
}

上面为“编译出错”的代码,下面为“成功完成”的代码 

RandomAccessFile——随意(任意)访问文件

Random——想访问文件的哪个点,就访问文件的哪个点(任意)

RandomAccessFile实现了Closeable接口,所以可以使用自动关闭资源的try语句

特征

1、既可读、又可写、还可追加。相当于InputStream与OutputStream合体。

      RandomAccessFile它不会覆盖原有的文件内容。

2、只能访问文件!这就是它的局限性。

import java.io.*;
public class RandomAccessFileTest {public static void main(String[] args) {try (// 使用RadomAccessFile创建一个只读的输入流RandomAccessFile raf = new RandomAccessFile("RandomAccessFileTest.java", "r");){byte[] buff = new byte[1024];int hasRead = -1;while ((hasRead = raf.read(buff)) > 0) {System.out.println(new String(buff, 0, hasRead));}} catch (Exception ex) {ex.printStackTrace();}}
}

创建RandomAccessFile,需要指定读(r)、写(rw)模式

体现它的“random【任意】”性的方法

seek(long pos)——用于把记录指针移动到任意位置,想访问哪个点就访问哪个点。

一开始,它的记录指针位于文件的开始位置。

使用RandomAccessFile来追加文件内容

1、把记录指针移动到最后

2、执行输出即可

import java.io.RandomAccessFile;public class AppendTest {public static void main(String[] args) {try (// 使用RadomAccessFile创建一个只读的输入流RandomAccessFile raf = new RandomAccessFile("AppendTest.java", "rw");){// 把记录指针移动到文件的最后raf.seek(raf.length());raf.write("//做人好累".getBytes());	} catch (Exception ex) {ex.printStackTrace();}}
}

使用RandomAccessFile来插入文件内容

1、把记录指针移动到指定位置

2、从当前位置到文件结尾的内容,先读取,并保存

3、输出要插入的内容

序列化

Java对象(内存)->二进制流

目的

1、在有些时候,需要把对象存储到外部存储器中持久化保存。

2、在有些时候,需要把对象通过网络传输。

可序列化的对象

Java要求序列化的类实现下面任意两个接口

1、Serializable:接口只是一个标记性的接口,实现该接口无需实现任何方法

2、Externalizable:实现该接口要实现方法。

序列化的IO流

  ObjectInputStream——负责从二进制流“恢复”对象。readObject

ObjectOutputStream——负责把对象保存到二进制流中。writeObject

import java.io.*;
class Apple implements Serializable{private String name;private String color;private double weight;public Apple() {super();}public Apple(String name, String color, double weight) {super();this.name = name;this.color = color;this.weight = weight;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}public String toString() {return "Apple[name=" + name +",color=" + color+ ",weight=" + weight + "]";}
}public class WriteObject {public static void main(String[] args) {Apple ap = new Apple("红富士", "红色", 3.4);System.out.println(ap);// 当程序结束时,虚拟机退出,内存中的Apple对象就被销毁了try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("app.bin"));) {oos.writeObject(ap); //把ap对象写入app.bin文件中}catch (Exception ex) {// TODO: handle exception}}
}

import java.io.*;
public class ReadObject {public static void main(String[] args) {try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("app.bin"));){Apple ap = (Apple)ois.readObject();System.out.println(ap);}catch (Exception ex) {ex.printStackTrace();}}
}

序列化机制

总结

Java传统IO的基本体系

字节输入流字节输出流字符输入流字符输出流
访问文件InputStreamOutputStreamReaderWriter
访问数组FileXxx
访问管道ByteArrayXxxCharArrayXxx
访问字符串StringXxx
过滤流FilterInputStreamFilterOutputStreamFilterReaderFilterWriter
打印流PrintStreamPrintWriter
转换流InputStreamReaderOutputStreamWriter
特殊流DataInputStreamDataOutputStream
ObjectInputStreamObjectOutputStream

RandomAccessFile

1、它只能访问文件。相当于DataInputStream和DataOutputStream组合

2、任意,由seek(int pos)。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】写入访问权限冲突

访问权限冲突 一、引入:情景再现二、出现问题的原因三、解决问题的方法四、问题解决五、结果修正 一、引入:情景再现 想在结构体堆的数组中for循环读入已经有的一个数组 int main() {int a[] { 2,3,5,7,4,6,8,65,100,70,32,50,60 };int num sizeof(a…

订单 延后自动关闭,五种方案优雅搞定!

前 言 在开发中,往往会遇到一些关于延时任务的需求。例如 生成订单30分钟未支付,则自动取消生成订单60秒后,给用户发短信 对上述的任务,我们给一个专业的名字来形容,那就是延时任务 。那么这里就会产生一个问题,这个…

何为心理承受能力?如何提高心理承受能力?

心理承受能力,也可以理解为人的抗压能力,指的是承受压力,承受逆境的能力。人的一生其实就是在不断的解决问题,见招拆招,遇到问题解决问题,在我们不断学习和锻炼的过程中,提高了我们解决问题的效…

nginx常见报错及解决acme.sh给Nginx配置SSL证书

问题排查: nginx -t //检查配置是否正确只要返回ok就说明配置没问题。 Nginx报错Failed to restart nginx.service: Unit not found 解决方法: 1、在根目录下执行 vim /etc/init.d/nginx2、插入以下代码 #!/bin/sh # nginx - this script starts …

【网络爬虫】2 初探网络爬虫

爬虫练手 把豆瓣的书评list页爬取下来,并获取其书名,和detail的连接地址 豆瓣的书评list的url地址, start1,2,3,4…是其地址页 https://book.douban.com/top250?start1 f12 观察其html结构 思路 按照找到的list的页面地址: 1.获取list页…

15 Transformer 框架概述

整体框架 机器翻译流程(Transformer) 通过机器翻译来做解释 给一个输入,给出一个输出(输出是输入的翻译的结果) “我是一个学生” --》(通过 Transformer) I am a student 流程 1 编码器和解…

最详细STM32,cubeMX外部中断

这篇文章将详细介绍 cubeMX外部中断的配置,实现过程。 文章目录 前言一、外部中断的基础知识。二、cubeMX 配置外部中断三、自动生成的代码解析四、代码实现。总结 前言 实验开发板:STM32F103C8T6。所需软件:keil5 , cubeMX 。实…

用git stash暂存修改

git stash命令用于保存当前工作目录的临时状态,包括暂存区和已修改但未暂存的文件。它会将这些修改保存在一个临时区域(即“堆栈”)中,让你能够回到一个干净的工作目录,可以进行其他操作。等到你完成其他任务后&#x…

openGauss学习笔记-105 openGauss 数据库管理-管理用户及权限-默认权限机制

文章目录 openGauss学习笔记-105 openGauss 数据库管理-管理用户及权限-默认权限机制 openGauss学习笔记-105 openGauss 数据库管理-管理用户及权限-默认权限机制 数据库对象创建后,进行对象创建的用户就是该对象的所有者。openGauss安装后的默认情况下&#xff0c…

深度学习推荐系统架构、Sparrow RecSys项目及深度学习基础知识

文章目录 🌟 技术架构:深度学习推荐系统的经典技术架构长啥样?🍊 一、深度学习推荐系统的技术架构🍊 二、基于用户行为的推荐🍊 三、基于多模态数据的推荐🍊 四、基于知识图谱的推荐 &#x1f3…

layui 表格 展开

一、表格嵌套表格&#xff08;手风琴打开&#xff09; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>设备上下线统计</title><script type"text/javascript" src"../../../l…

使用Vue组件的watch监听-简单计算器

Vue组件的初探 一、浅析 这里做了一个全局的组件vue.component(mycomp,{}) 在<template></template>中写组件&#xff0c;将idcomp1 script中直接template:"#copm1" 其他的部分就是之前所讲的watch来实现简易计算器差不多 <div id"app"&…

C/C++ const相关 常量指针 常指针 常指针常量 顶层底层const

文章目录 前言const限定符初始化const引用指针和const顶层和底层const总结 前言 在看const相关内容的时候&#xff0c;对const的一些概念还存在部分疑惑&#xff0c;容易搞混&#xff0c;尤其是在变量声明这种情况下。 这篇博客就主要写一下const的相关。 const限定符 const主…

如何实现前端实时通信(WebSocket、Socket.io等)?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

架构案例分析重点

架构案例分析重点 信息系统架构架构图 层次式架构&#xff08;可能考点&#xff09;表现层框架设计中间层架构设计数据访问层数据访问层工厂模式的设计&#xff08;一个考点&#xff09; 物联网三层 云原生架构面向服务架构(SOA)SOA设计模式 嵌入式系统架构鸿蒙操作系统&#x…

[C国演义] 第十六章

第十六章 等差数列的划分最长递增子序列 等差数列的划分 力扣链接 子数组 ⇒ dp[i]的含义: yinums[i] 为结尾的所有子数组中的 等差数列数组最多的个数子数组⇒ 状态转移方程: 根据最后一个元素的构成 初始化: 涉及到 i-1, i-2 ⇒ 所以要初始化dp[0] 和 dp[1] 都初始化为 0…

【ES实战】ES主副分片数据不一致分析

ES主副分片数据不一致分析 文章目录 ES主副分片数据不一致分析问题描述问题重现问题分析修复方案 问题描述 在请求索引中的某一条数据时&#xff0c;时而查询有结果&#xff0c;时而无结果。两种情况交替出现。 问题重现 通过对问题数据的点查&#xff0c;确实重现了该现象 …

hdlbits系列verilog解答(或非门)-07

文章目录 wire线网类型介绍一、问题描述二、verilog源码三、仿真结果 wire线网类型介绍 wire线网类型是verilog的一种数据类型&#xff0c;它是一种单向的物理连线。它可以是输入也可以是输出&#xff0c;它与reg寄存器数据类型不同&#xff0c;它不能存储数据&#xff0c;只能…

性能优化-卡顿优化-tarce抓取及分析

性能优化&#xff08;卡顿分析&#xff09; 文章目录 一、抓取trace的方法1.使用systrace抓取trace2.使用atrace抓取3.使用Perfetto抓取trace 二、trace文件的分析1.快捷操作1.1 导航操作1.2 快捷操作 2.chrome trace工具分析trace文件3.Prefetto分析trace文件 一、抓取trace的…

[Leetcode] 0035. 搜索插入位置

35. 搜索插入位置 题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target …