文章目录
- 前言
- 一、IO是什么?
- 二、类库分析
- File类
- OutputStream类
- InputStream
- Writer类
- Reader类
- Serializable接口
- 三、io类结构图
- 流io
- 四、转换流
- 五、缓冲流
- 相关代码使用
前言
浅浅收录一下Java路上第一个坎
一、IO是什么?
I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
IO流也是Java重要的一个构成部分,在Java中I/O操作主要是指使用Java进行输入、输出操作,Java所有的I/O流都是基于数据流,这些数据流表示字符或字节数据的流动序列。
二、类库分析
在整个Java.io包中,最重要的是五个类+一个接口,具体是指
- File类
- OutputStream类
- InputStream类
- Writer类
- Reader类
- Serializable接口
File类
File类(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。
构造器
(1)如果未指定父路径,则将会在当前目录下创建文件对象file;
(2) String pathname:该路径可以是以文件结尾,也可以是以文件夹结尾,该路径可以是存在,也可以是不存在的,该创建File对象,只是把字符串路径封装为File对象,不考虑路径的真假
(3)如果指定的父路径不存在,则会报错java.io.FileNotFoundException,需要使用mkdir()方法创建该目录。
(4)创建File对象时传入的路径使用了“\ \”,除此以外,目录符号还可以用正斜线“/”表示
(5)一般不使用url创建文件对象file,如果想要使用url,则需先判断url是否符合源码条件
注:若url不符合其构造条件,但仍需要对该url的资源做相关操作,则可尝试下列代码
URLConnection urlConn = url.openConnection();
InputStream input = urlConn.getInputStream();
常用方法
- boolean exists() 判断File对象对应的文件或目录是否存在,若存在返回ture,不存在返回false boolean
- delete() 删除File对象对应的文件或目录,若成功删除返回true,否则返回false boolean
- createNewFile()
当File对象对应的文件不存在时,该方法会新建一个此File对象所指定的新文件,若创建成功则返回true,否则返回false String - getName() 返回File对象表示的文件或文件夹的名称 String getPath() 返回File对象对应的路径 String
- getAbsolutePath()
返回File对象对应的绝对路径,注意(在Linux等系统上,如果路径是以“\”开始,则这个路径是绝对路径;在Windows等系统上,如果路径是从盘符开始,则这个路径是绝对路径) - String getParentFile() 返回File对象对应目录的父目录(即返回的目录不包含最后一级子目录) boolean
- canWrite() 判断File对象对应的文件或目录是否可写,若可写则返回true,反之返回false boolean
- canRead() 判断File对象对应的文件或目录是否可读,若可读则返回true,反之返回false boolean
- isDirectory() 判断File对象对应的是否是目录(不是文件),若是目录则返回true,反之返回false boolean
- isFile() 判断File对象对应的是否是文件(不是目录),若是文件则返回true,反之返回false boolean
- isAbsolute() 判断File对象对应的文件或目录是否是绝对路径 long lastModified()
- 返回1970年1月1日0时0分0秒到文件最后修改时间的毫秒值 String[] list() 列出指定目录的全部内容,只是列出名称
- long length() 返回文件内容的长度 File[] listFiles()
返回一个包含了File对象所有子文件和子目录的File数组
OutputStream类
OutputStream类,此抽象类是表示输出字节流的所有类的超类。 输出流接受输出字节并将它们发送到某个接收器。
需要定义OutputStream的子类的应用程序必须始终至少提供一个写入一个输出字节的方法。
常用方法
- void write(int b)
将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 即写入0~255范围的。 - void write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该与调用 write(b, 0, b.length) 的效果完全相同。 - void write(byte[] b,int off,int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。 - public void flush()throws IOException
刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立即写入它们预期的目标。 - public void close() throws IOException
关闭此输出流并释放与该流关联的所有系统资源。
InputStream
InputStream类,此抽象类是表示输入字节流的所有类的超类。
需要定义子类InputStream应用程序必须始终提供返回输入的下一个字节的方法
常用方法
- int read()
从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。 - int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取的字节数。 - int read(byte[] b, int off,int len)
将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于文件末尾而没有可用的字节,则返回值 -1。 - public void close() throws IOException
关闭此输入流并释放与该流关联的所有系统资源。 - public int available() throws IOException
返回输入流中可用的字节数 - public void mark(int readlimit)
标记输入流中数据已被读取到的位置 - public void reset() throws IOException
返回流中设置mark标记的点 - public boolean markSupported()
检查流中是否支持mark()和reset()方法 - public long skip(long n) throws IOException
跳过并丢弃输入流中指定的字节数
Writer类
用于写入字符流的抽象类。 子类必须实现的唯一方法是write(char [],int,int),flush()和close()。 但是,大多数子类将覆盖此处定义的一些方法,以提供更高的效率,附加功能或两者兼而有之。
常用方法
- void write(int c)
写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。 即写入0 到 65535 之间的Unicode码。 - void write(char[] cbuf)
写入字符数组。 - void write(char[] cbuf,int off,int len)
写入字符数组的某一部分。从off开始,写入len个字符 - void write(String str)
写入字符串。 - void write(String str,int off,int len)
写入字符串的某一部分。 - void flush()
刷新该流的缓冲,则立即将它们写入预期目标。 - public void close() throws IOException
关闭此输出流并释放与该流关联的所有系统资源。
常用子类
- CharArrayWriter类-向内存缓冲区的字符数组写数据。
- StringWriter类-向内存缓冲区的字符串(StringBuffer)写数据。
- BufferedWriter类-为其他字符输出流提供写缓冲区。
- PipedWriter类-连接到一个 PipedReader。
- OutputStreamReader类-将字节输出流转换为字符输出流,可以指定字符编码
Reader类
用于读取字符流的抽象类。 子类必须实现的唯一方法是read(char [],int,int)和close()。 但是,大多数子类将覆盖此处定义的一些方法,以提供更高的效率,附加功能或两者兼而有之。
常用方法
- public int read()
从输入流中第一个字符 - public inr read(char[] cbuf)
从输入流中读最多cbuf.length个字符,存入字符数组cbuf中 - public inr read(char[] cbuffer,int off,int len)
从输入流中读最多len个字符,存入字符数组cbuffer中,从off开始的位置 - public long skip(long n)
从输入流中最多向后跳n个字符 - public boolean ready()
判断流是否做好读的准备 - public void mark(int readAheadLinit)
标记输入流的当前位置 - public boolean markSupported()
测试输入流是否支持mark - public void reset()
重新定位输入流 - public void close()
关闭输入流
Serializable接口
Serializable是Java提供的序列化接口,是一个空接口,为对象提供标准的序列化与反序列化操作。使用Serializable实现序列化过程相当简单,只需要在类声明的时候指定一个标识,便可以自动的实现默认的序列化过程
三、io类结构图
流io
标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,一组有序,有起点和终点的字节的数据序列。包括输入流和输出流,java中将输入输出抽象称为流,将数据从外存中读取到内存中的称为输入流,将数据从内存写入外存中的称为输出流。
(1)输出
把程序(内存)中的内容输出到存储设备中
程序–输出–>文件
(2)输入
读取外部数据到程序(内存)中
程序<–输入–文件
(3) Input Stream不关心数 据源来自何种设备(键盘,文件,网络)而Output Stream不关心数据的目的是何种设备(键盘,文件,网络)
(4)数据流的分类
流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据
Java中的流分为两种:
- 字节流:数据流中最小的数据单元是字节
- 字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节
标准I/O:
Java程序可通过命令行参数与外界进行简短的信息交换,也规定了与标准输入、输出设备进行信息交换的方式,而通过文件可以与外界进行任意数据形式的信息交换
1)命令行参数:
查看----->命令行参数文档
2)标准输入、输出数据流
java系统自带的标准数据流:java.lang.System:
注意:
System类不能创建对象,只能直接使用它的三个静态成员
每当main方法被执行时,就自动生成上述三个对象
public final class System extends Object{
static PrintStream err;//标准错误流(输出)
static InputStream in;//标准输入(键盘输入流)
static PrintStream out;//标准输出流(显示器输出流)
}
1.标准输出流 System.out
System.out向标准输出设备输出数据,其数据类型为PrintStream
方法:
Void print(参数)
Void println(参数)
2.标准输入流 System.in
System.in读取标准输入设备数据,其数据类型为InputStream
方法:
int read() //返回ASCII码。若,返回值=-1,说明没有读取到任何字节读取工作结束
int read(byte[] b)//读入多个字节到缓冲区b中返回值是读入的字节数
3.标准错误流System.err
System.err输出标准错误,其数据类型为PrintStream
更多详见源码咯
四、转换流
转换流是字节流通向字符流的桥梁,可以将字节流转换为字符流,原理其实就是在字节流的基础上增加了编解码的操作。
为什么需要转换流
例如在IDEA中,使用 FileReader字符输入流 读取项目中的文本文件。由于IDEA的设置,都是默认的UTF-8 编码,所以没有任何问题。但是,当读取Windows系统中创建的文本文件时,由于Windows系统的默认是GBK编码,就会出现乱码。
InputStreamReader类
转换流java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。
构造方法InputStreamReader(InputStream in)
: 创建一个使用默认字符集的字符流。InputStreamReader(InputStream in, String charsetName)
: 创建一个指定字符集的字符流。
InputStreamReader isr = new InputStreamReader(new FileInputStream("in.txt"));
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("in.txt") , "GBK");
OutputStreamWriter类
转换流 java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集讲字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。
构造方法OutputStreamWriter(FileOutputStream in)
: 创建一个使用默认字符集的字符流。OutputStreamWriter(FileOutputStream in, String charsetName)
: 创建一个指定字符集的字符流。
OutputStreamWriter isr = new OutputStreamWriter(new FileOutputStream("out.txt"));
OutputStreamWriter isr2 = new OutputStreamWriter(new FileOutputStream("out.txt") , "GBK");
五、缓冲流
不带缓冲的流,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。
带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!
缓冲流的分类:
字符缓冲流:BufferedReader和BufferedWriter
字节缓冲流:BufferedInputStream和BufferedOutputStream
BufferedInputStream和BufferedOutputStream这两个类分别是FilterInputStream和FilterOutputStream的子类。作为装饰器子类,使用它们可以防止每次读取/发送数据时进行实际的写操作,代表着使用缓冲区。
相关代码使用
package xsjStudy;
import java.io.*;
public class Review3 {
/**
* IO
*/
public static void main(String[] args) throws IOException {
// fileWriterTest();
// fileReaderTest();
// outputStreamTest();
// inputStreamTest();
// ReaderWriterClone();
// streamClone();
// bufferedInputStreamTest();
// bufferedOutputStreamTest();
// bufferedStreamClone();
// bufferedRWClone();
}
/**
* 字符流 输出
*/
public static void fileReaderTest() throws IOException {
File file = null;
file = new File("./src/xsjStudy/dest.txt");
Reader reader = new FileReader(file);
int b = 0;
while ((b = reader.read()) != -1) {
System.out.print((char)b);
}
reader.close();
}
/**
* 字符流 输入
*/
public static void fileWriterTest() throws IOException {
File file = null;
file = new File("./src/xsjStudy/dest.txt");
Writer writer = new FileWriter(file,true);
String str = "aaaccc";
writer.write(str);
writer.close();
}
/**
* 字节流 输入
*/
public static void inputStreamTest() throws IOException {
File file = null;
file = new File("./src/xsjStudy/dest.txt");
InputStream inputStream = new FileInputStream(file);
int b = 0;
while ((b = inputStream.read()) != -1) {
System.out.print((char)b);
}
inputStream.close();
}
/**
* 字节流 输出
*/
public static void outputStreamTest() throws IOException {
File file = null;
file = new File("./src/xsjStudy/dest.txt");
OutputStream outputStream = new FileOutputStream(file,true);
String str = "aaacccbbb";
byte[] b = str.getBytes();
outputStream.write(b);
outputStream.close();
}
/**
* ----字符流 复制------
*/
public static void ReaderWriterClone() throws IOException {
File file1 = null;
file1 = new File("./src/xsjStudy/dest.txt");
Reader reader = new FileReader(file1);
Writer writer = new FileWriter(new File("./src/xsjStudy/dest1.txt"));
int b = 0;
while ((b = reader.read()) != -1) {
writer.write(b);
}
reader.close();
writer.close();
}
/**
* ----字节流 复制------
*/
public static void streamClone() throws IOException {
File file1 = null;
file1 = new File("./src/xsjStudy/dest.txt");
InputStream inputStream = new FileInputStream(file1);
OutputStream outputStream = new FileOutputStream(new File("./src/xsjStudy/dest3.txt"));
int b = 0;
while ((b = inputStream.read()) != -1) {
outputStream.write(b);
}
inputStream.close();
outputStream.close();
}
/**
* 转换流
* InputStreamReader用于将字节输入流转换为字符输入流
* OutputStreamWriter用于将字节输出流转换为字符输出流
*
* FileInputStream fis = new FileInputStream("D:/test.txt");
* InputStreamReader isr = new InputStreamReader(fis,"UTF-8");//解决编码错误问题
*
*/
public static void method() throws IOException {
InputStreamReader isr = null;
OutputStreamWriter osw = null;
File file1 = new File("d:/io/hello_utf8.txt");
File file2 = new File("d:/io/hello_gbk.txt");
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
isr = new InputStreamReader(fis);
osw = new OutputStreamWriter(fos, "gbk");
char[] cbuf = new char[1024];
int len;
while ((len = isr.read(cbuf)) != -1) {
for (int i = 0; i < len; i++) {
osw.write(cbuf[i]);
}
}
}
/**
* 字节缓冲流 读取
*/
public static void bufferedInputStreamTest() throws IOException{
File file1 = null;
file1 = new File("./src/xsjStudy/dest.txt");
InputStream inputStream = new FileInputStream(file1);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
byte[] bytes = new byte[1024];
int b = 0;
while ((b = bufferedInputStream.read(bytes))!=-1){
System.out.println(new String(bytes,0,b));// 0 起始位置 b 终止位置
}
bufferedInputStream.close();
inputStream.close();
}
/**
* 字节缓冲流 写入
*/
public static void bufferedOutputStreamTest() throws IOException{
File file1 = null;
file1 = new File("./src/xsjStudy/dest.txt");
OutputStream outputStream = new FileOutputStream(file1);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
String str = "asdniuewugbycudwbddsujnb";
byte[] bytes = str.getBytes();
bufferedOutputStream.write(bytes);
bufferedOutputStream.close();
outputStream.close();
}
/**
* -----字节缓冲流 复制-------
*/
public static void bufferedStreamClone() throws IOException{
File file1 = null;
file1 = new File("./src/xsjStudy/dest1.txt");
InputStream inputStream = new FileInputStream(file1);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
OutputStream outputStream = new FileOutputStream(new File("./src/xsjStudy/dest4.txt"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
int b = 0;
while ((b = bufferedInputStream.read())!=-1){
bufferedOutputStream.write(b);
}
bufferedInputStream.close();
inputStream.close();
bufferedOutputStream.close();
outputStream.close();
}
/**
* 字符缓冲流 读取
*/
public static void bufferedReaderTest() throws IOException {
File file1 = null;
file1 = new File("./src/xsjStudy/dest1.txt");
Reader reader = new FileReader(file1);
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine())!=null){
System.out.println(line);
}
bufferedReader.close();
reader.close();
}
/**
* 字符缓冲流 写入
*/
public static void bufferedWriterTest() throws IOException {
File file1 = null;
file1 = new File("./src/xsjStudy/dest.txt");
Writer writer = new FileWriter(file1);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
String str = "sduvbiwncwv w";
bufferedWriter.write(str);
bufferedWriter.newLine();// 写入一个行分隔符
writer.close();
bufferedWriter.close();
}
/**
* ------字符缓冲流 复制------
*/
public static void bufferedRWClone() throws IOException{
File file1 = null;
file1 = new File("./src/xsjStudy/dest1.txt");
Writer writer = new FileWriter(new File("./src/xsjStudy/dest6.txt"));
BufferedWriter bufferedWriter = new BufferedWriter(writer);
Reader reader = new FileReader(file1);
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while((line = bufferedReader.readLine())!=null){
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedWriter.close();
bufferedReader.close();
writer.close();
reader.close();
}
/**
* 其他
* (1)
* fileNames = file.list((dir, name) -> name.endsWith(".txt"));
*/
}