- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
输入/输出处理是程序设计中非常重要的环节, 如从键盘或传感器读入数据、 从文件中读取数据或向文件中写入数据、 从网络中读取或写入数据等。 Java 把这些不同类型的输入、 输出抽象为 “流” , 所有的输入/输出以流的形式进行处理。I表示Input,O表示Output,通过IO可以完成硬盘文件的读和写。
在java中只要“类名”以Stream结尾的都是字节流。以“Reader/Writer”结尾的都是字符流
文件专属:
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter
转换流:(将字节流转换成字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
缓冲流专属:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream
数据流专属:
java.io.DataInputStream
java.io.DataOutputStream
标准输出流:
java.io.PrintWriter
java.io.PrintStream
对象专属流:
java.io.ObjectInputStream
java.io.ObjectOutputStream
InputStream 和 OutputStream 继承结构图:
返回值类型 | 方法名 | 描述 |
---|---|---|
void | close() | 关闭此流并释放与该流关联的所有系统资源 |
abstract int | read() | 从输入流读取下一个数据字节.再读的时候读取不到任何数据返回-1 |
int | read(byte[] b) | 从输入流中读取一定数量的字节并将其存储在缓冲区数组 b 中 |
int | read(byte[] b, int off, int len) | 将输入流中最多 len 个数据字节读入字节数组 |
void | flush() | 刷新此输出流并强制写出所有缓冲的输出字节 |
void | write(byte[] b) | 将 b.length 个字节从指定的字节数组写入此输出流 |
void | write(byte[] b, int off, int len) | 将指定字节数组中从偏移量 off 开始的 len 个字节写入此输出流 |
abstract void | write(int b) | 将指定的字节写入此输出流 |
Reader 和 Writer 继承结构图:
返回值类型 | 方法名 | 描述 |
---|---|---|
abstract void | close() | 关闭该流 |
int | read() | 读取单个字符 |
int | read(char[] cbuf) | 将字符读入数组 |
abstract int | read(char[] cbuf, int off, int len) | 将字符读入数组的某一部分 |
Writer | append(char c) | 将指定字符追加到此 writer |
abstract | void flush() | 刷新此流 |
void | write(char[] cbuf) | 写入字符数组 |
abstract void | write(char[] cbuf, int off, int len) | 写入字符数组的某一部分 |
void | write(int c) | 写入单个字符 |
void | write(String str) | 写入字符串 |
void | write(String str, int off, int len) | 写入字符串的某一部分 |
File 类是 java.io 包中唯一代表磁盘文件和目录的类。 File类和四大家族没有关系,所以File类不能完成文件的读和写。
File dir = new File("D:/java/tt/");//创建目录
File file = new File("D:/java/tt/file.txt");//创建文件
File file = new File(dir,"file1.txt");//在dir目录下创建文件
File file = new File("D:/java/tt/","file2.txt");//在tt目录下创建文件
返回类型 | 方法名 | 描述 |
---|---|---|
boolean | exits( ) | 判断文件是否存在 |
boolean | createNewFile() | 以文件形式新建 |
boolean | mkdir() | 以目录的形式新建 |
boolean | mkdirs() | 多重目录的形式新建 |
boolean | delete( ) | 删除 File 对象对应的文件或目录 |
boolean | isFile( ) | 判断文件是否是文件 |
boolean | isDirectory( ) | 判断文件是否是目录 |
boolean | canRead( ) | 判断文件是否可读 |
boolean | canWrite( ) | 判断文件是否可写 |
long | length( ) | 获取文件的长度 (单位时字节) |
long | lastModified() | 获取文件最后一次修改时间,返回从1970年到现在的总毫秒数 |
String | getName( ) | 获取文件的名字 |
String | getPath( ) | 返回 File 对象对应的路径 |
String | getAbsolutePath( ) | 获取文件的绝对路径 |
String | getParent( ) | 获取文件的父目录 |
String[] | list( ) | 列出指定目录的全部内容,只列出名称 |
File[ ] | listFiles( ) | 返回包含 File 对象所有子文件和子目录的 File 数组 |
文件流主要分为
FileInputStream
1、文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
2、字节的方式,完成输入的操作,完成读的操作(硬盘 → 内存)
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("chapter23/src/tempfile3");
// 准备一个byte数组,一次最多读取4个字节
byte[] bytes = new byte[4];
int readCount = 0;
//is.read(bytes)的返回值是:读取到的字节数量,不是字节本身
while((readCount = fis.read(bytes)) != -1) {
//将字节数组全部转换成字符串
System.out.print(new String(bytes, 0, readCount));
}
} catch (IOException e) {
e.printStackTrace();
} finally { //在finally语句块当中确保流一定关闭
if (fis != null) {
try {
fis.close();//关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileInputStream类的其它常用方法:
FileOutputStream
字节的方式,完成输出的操作,完成写的操作(内存 → 硬盘)
public class FileOutputStreamTest {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//文件不存在的时候会自动新建!
// 这种方式谨慎使用,这种方式会先将原文件清空,然后重新写入。
//fos = new FileOutputStream("D:\\IO\\why\\b.txt");
// 以追加的方式在文件末尾写入。不会清空原文件内容。
fos = new FileOutputStream("D:\\IO\\why\\b.txt", true);
byte[] bytes = {97, 98, 99, 100};
// 将byte数组全部写出
fos.write(bytes); // abcd
// 将byte数组的一部分写出
fos.write(bytes, 0, 2); // 再写出ab
String s = "我是输出流";
// 将字符串转换成byte数组。
byte[] bs = s.getBytes();
fos.write(bs);
fos.flush();// 写完之后,最后一定要刷新
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流(代码省略)
}
}
}
FileReader
文件字符输入流,只能读取普通文本。读取文本内容时,比较方便快捷。
public class FileReaderTest {
public static void main(String[] args) {
FileReader reader = null;
try {
//创建文件字符输入流
reader = new FileReader("D:\\IO\\why\\b.txt");
//开始读
char[] chars = new char[4]; // 一次读取4个字符
int readCount = 0;
while((readCount = reader.read(chars)) != -1) {
System.out.print(new String(chars,0,readCount));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流(代码省略)
}
}
}
FileWriter
文件字符输出流,负责写。只能输出普通文本
public class FileWriterTest {
public static void main(String[] args) {
FileWriter out = null;
try {
out = new FileWriter("D:\\IO\\why\\c.txt", true);
char[] chars = {'我','是','中','国','人'};
out.write(chars); //将我是中国人写入到文件
out.write(chars, 2, 3);//将中国人写入到文件
out.write("我是一名java软件工程师!");
out.write("\n");// 写出一个换行符。
out.write("hello world!");
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流(代码省略)
}
}
}
缓冲流主要是为了提高效率而存在的,减少物理读取次数,缓冲流主要有:
BufferedReader
带有缓冲区的字符输入流。 使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组,自带缓冲。
public class BufferedReaderTest {
public static void main(String[] args) throws Exception{
FileReader reader = new FileReader("D:\\IO\\why\\a.txt");
// 当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流
// 外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流
// FileReader就是一个节点流BufferedReader就是包装流/处理流。
BufferedReader br = new BufferedReader(reader);
// 读一行但不带换行符
//String firstLine = br.readLine();
String s = null;
while((s = br.readLine()) != null){
System.out.print(s);
}
// 对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭
br.close();
}
}
BufferedWriter
带有缓冲的字符输出流
public class BufferedWriterTest {
public static void main(String[] args) throws Exception{
// 带有缓冲区的字符输出流
BufferedWriter out = new BufferedWriter(new FileWriter("copy"));
// 开始写
out.write("hello world!");
out.write("\n");
out.write("hello kitty!");
// 刷新
out.flush();
// 关闭最外层
out.close();
}
}
转换流主要有两个 InputStreamReader 和 OutputStreamWriter
//字节输入流
FileInputStream in = new FileInputStream("Copy02.java");
//通过转换流转换(InputStreamReader将字节流转换成字符流)
InputStreamReader reader = new InputStreamReader(in);
//字节输出流
FileOutputStream out = new FileOutputStream("copy", true);
//通过转换流转换(OutputStreamWriter将字节流转换成字符流)
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out);
标准输出流主要包含两个:
PrintStream
System.out 其实对应的就是 PrintStream,默认输出到控制台,我们可以重定向它的输出,可以定向到文件,也就是执行 System.out.println(“hello”)不输出到屏幕,而输出到文件
public class PrintStreamTest {
public static void main(String[] args) throws Exception{
//默认输出到控制台
System.out.println("hello world!");
//标准输出流不再指向控制台,指向“log”文件。
PrintStream printStream = new PrintStream(new FileOutputStream("log"));
//修改输出方向,将输出方向修改到"log"文件。
System.setOut(printStream);
//再输出
System.out.println("hello world");
System.out.println("hello kitty");
System.out.println("hello zhangsan");
//标准输出流不需要手动close()关闭
}
}
PrintWriter
PrintWriter printWriter = new PrintWriter(new FileWriter("D:\\IO\\why\\f.txt"));
printWriter.print("我是printWriter");
printWriter.flush();
printWriter.close();
数据流包含两个:
DataOutputStream
这个流可以将数据连同数据的类型一并写入文件
注意:这个文件不是普通文本文档
public class DataOutputStreamTest {
public static void main(String[] args) throws Exception{
// 创建数据专属的字节输出流
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data"));
byte b = 100;
short s = 200;
int i = 300;
long l = 400L;
float f = 3.0F;
double d = 3.14;
boolean sex = false;
char c = 'a';
// 把数据以及数据的类型一并写入到文件当中
dos.writeByte(b);
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(l);
dos.writeFloat(f);
dos.writeDouble(d);
dos.writeBoolean(sex);
dos.writeChar(c);
dos.flush();//刷新
dos.close();//关闭最外层流
}
}
DataInputStream
DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候你需要提前知道写入的顺序。读的顺序需要和写的顺序一致。才可以正常取出数据
public class DataInputStreamTest01 {
public static void main(String[] args) throws Exception{
//创建数据输入流
DataInputStream dis = new DataInputStream(new FileInputStream("data"));
// 开始读,读的顺序需要和写的顺序一致
byte b = dis.readByte();
short s = dis.readShort();
int i = dis.readInt();
long l = dis.readLong();
float f = dis.readFloat();
double d = dis.readDouble();
boolean sex = dis.readBoolean();
char c = dis.readChar();
System.out.println(b);
System.out.println(s);
System.out.println(i + 1000);
System.out.println(l);
System.out.println(f);
System.out.println(d);
System.out.println(sex);
System.out.println(c);
dis.close();
}
}
对象流可以将 Java 对象转换成二进制写入磁盘,这个过程通常叫做序列化,并且还可以从磁盘读出完整的 Java 对象,而这个过程叫做反序列化。对象流主要包括ObjectInputStream 和 ObjectOutputStream
ObjectOutputStream
public class Student implements Serializable {
// IDEA工具自动生成序列化版本号。
//private static final long serialVersionUID = -7998917368642754840L;
// 建议将序列化版本号手动的写出来。不建议自动生成
private static final long serialVersionUID = 1L; // java虚拟机识别一个类的时候先通过类名,如果类名一致,再通过序列化版本号。
private int no;
private String name;
public Student(int no, String name) {
this.no = no;
this.name = name;
}
/*setter and getter 方法*/
/*toString()方法*/
}
序列化对象
public class ObjectOutputStreamTest {
public static void main(String[] args) throws Exception{
// 创建java对象
Student s = new Student(1111, "张三");
// 创建对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students"));
// 序列化对象
oos.writeObject(s);
// 刷新
oos.flush();
// 关闭
oos.close();
}
}
ObjectInputStream
反序列化对象
public class ObjectInputStreamTest {
public static void main(String[] args) throws Exception{
//创建对象输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("students"));
// 开始反序列化,读
Object obj = ois.readObject();
// 反序列化回来是一个学生对象,所以会调用学生对象的toString方法。
System.out.println(obj);
ois.close();
}
}
经常改变的数据,可以单独写到一个文件中,使用程序动态读取。将来只需要修改这个文件的内容,java代码不需要改动,不需要重新编译,服务器也不需要重启。就可以拿到动态的信息。
类似于以上机制的这种文件被称为配置文件。
并且当配置文件中的内容格式是:
key1=value
key2=value
public class IoPropertiesTest {
public static void main(String[] args) throws Exception{
/*
Properties是一个Map集合,key和value都是String类型。
想将userinfo文件中的数据加载到Properties对象当中。
*/
// 新建一个输入流对象
FileReader reader = new FileReader("chapter23/userinfo.properties");
// 新建一个Map集合
Properties pro = new Properties();
// 调用Properties对象的load方法将文件中的数据加载到Map集合中
// 文件中的数据顺着管道加载到Map集合中,其中等号=左边做key,右边做value
pro.load(reader);
// 通过key来获取value呢?
String username = pro.getProperty("username");
System.out.println(username);
String password = pro.getProperty("password");
System.out.println(password);
String data = pro.getProperty("data");
System.out.println(data);
String usernamex = pro.getProperty("usernamex");
System.out.println(usernamex);
}
}
我试图将形状对象的当前位置添加到我的数组列表中,但是当对象位置更改时,我的列表对象也会更改.. 经过几个小时的搜索,我发现了一种不同的方式,现在即使对象位置发生变化,位置也保持不变 这是我的第一个导致
这个问题在这里已经有了答案: Java FileReader encoding issue (6 个答案) 关闭 6 年前。 以下代码适用于具有英文内容但不适用于俄文内容的文件。如何让它也适用于俄语
有没有办法使用 Java 代码测试互联网速度? 比如我们实际是如何用cmd命令、ping命令进行测试的。 最佳答案 使用JSpeedTest库 SpeedTestSocket speedTestSoc
目录 方法重写 Override重写方法 重写小结: 总结 方法重写与之前
JavaSE: Java基础,我们入门所学的基础语法循环判断之后还有面向对象、网络编程、多线程、注解和反射、JVC、JUC等等。 学习地址:https://www.bilibili.com/video
我试图寻找一种方法来防止虚拟键盘在第一次将文本字段集中在 JavaSE 构建上时显示,但没有成功。 实现这一目标的最佳方法是什么? 最佳答案 在 init(Object) 方法中使用以下代码禁用该行为
我正在开发一个应该在 Android 和桌面(JavaSE)上运行的项目。为此,我将它分成 3 个 java 模块: 安卓应用 通用核心 桌面应用 为什么我使用 Android Studio (AS)
我叫弗拉基米尔,我想为我糟糕的英语道歉。 好的。我开始学习Java SE,我需要更多的练习来复习我的知识。我想比现在更好地了解这门语言。 您认为应该为初学者创建什么程序?也许带有数据库的服务器应用程序
我花了很长时间在 Java 中构建随机模拟。它们工作得很好,但公司的硬件不可靠,变旧并且不太可能很快被更换。 模拟和数字运算完全用 J2SE 编写。其中一些需要一点 GUI 交互,或者显示一个窗口以呈
鉴于最近 Oracle 对 Java 用户的明显打击(read here),我对继续使用 Oracle 的 JDK 或与此相关的任何 Oracle 持谨慎态度。上面的文章警告: “If you dow
这是我的 JavaSE 应用程序的数据库类。 public class db { static Connection c; public static Connection Get_C
我不知道问这个问题是否合适,但我在这里问。 到目前为止我尝试过的: 在我所有的 JavaSE(Swings、JavaFX) 等项目中,我都使用 MySQL、Oracle、MS SQL Server 作
是否可以在 JavaSE 中进行分布式事务?我听说过 Atomikos,但我很好奇是否可以只使用标准 Java。 最佳答案 不,JTA是一个Java EE API,需要由容器或库提供实现。 一些实现:
我想写一个简单的在线管理器。它将在 WebSocket 上工作。有没有允许使用像 onMessage 这样的方法的库?我的意思是没有像 这样的代码 is = new DataInputStream(c
我发现 sqlcipher 在 Android 开发中使用起来很方便。但它不能满足我的需求。最近,我接到一个任务,要在一个基于Java SE 的项目中加密一个sqlite 数据库。我的问题的核心是“我
我不清楚 JavaSE 和 JavaEE 之间的主要区别是什么!我想知道JavaSE是JavaEE的子集还是JavaEE与JavaSE完全不同。我还想知道JavaEE JDK是否包含JavaSE中包含
我正在制作一个小程序,用于将数据从我们不拥有的另一个系统迁移到我们公司内部制作的自定义系统。我将 IntelliJ 与 Maven 一起使用,但错误似乎来自构建后的目标文件夹,因为它似乎无法找到该文件
我从http://download.eclipse.org/jetty/stable-9/dist/下载了jetty 。 我可以启动/停止 Jetty 服务器。我还知道 eclipse wiki 上的
我目前正在设计一个 SDK,旨在用于桌面和 Web 应用程序。目前,我一直在使用 JavaSE-1.6 库并利用 Apache HttpComponents 库以及 JibX 库分别用于 Web 连接
Java SE 6 及更高版本与 Metro 捆绑在一起。令人惊讶的是,找不到 Java ver x -> Metro ver y 列表。 如何查明我的 JVM 捆绑了哪个版本的 Metro?通过在运
我是一名优秀的程序员,十分优秀!