原文
Java流
数据流是 Java 进行 I/O 操作的对象,它按照不同的标准可以分为不同的类别。
- 按照流的方向主要分为输入流和输出流两大类。
- 数据流按照数据单位的不同分为字节流和字符流。
- 按照功能可以划分为节点流和处理流。
- 所有输入流类都是 InputStream 抽象类(字节输入流)和 Reader 抽象类(字符输入流)的子类
- 在 Java 中所有输出流类都是 OutputStream 抽象类(字节输出流)和 Writer 抽象类(字符输出流)的子类

输入流InputSteam常用方法
int read(byte[] b,int off,int len)从输入流读入一个 8 字节的数据,将它转换成一个 0~ 255 的整数,返回一个整数,如果遇到输入流的结尾返回 -1
b可选, 保存到参数 b 指定的字节数组中off可选,开始保存数据位置的起始下标len可选,读取字节的位数
void close()关闭数据流,当完成对数据流的操作之后需要关闭数据流int available()返回可以从数据源读取的数据流的位数。skip(long n)从输入流跳过参数 n 指定的字节数目boolean markSupported()判断输入流是否可以重复读取,如果可以就返回 truevoid mark(int readLimit)如果输入流可以被重复读取,从流的当前位置开始设置标记,readLimit 指定可以设置标记的字节数void reset()使输入流重新定位到刚才被标记的位置,这样可以重新读取标记过的数据
一般我们会这样操作,首先使用
markSupported()判断,如果可以重复读取,则使用mark(int readLimit)方法进行标记,标记完成之后可以使用read()方法读取标记范围内的字节数,最后使用reset()方法使输入流重新定位到标记的位置,继而完成重复读取操作
Java中的字符是Unicode编码,即双字节的,而InputerStream是用来处理单字节的,在处理字符文本时不是很方便。这时可以使用Java的文本输入流Reader类,该类是字符输入流的抽象类,即所有字符输入流的实现都是它的子类,Reader与InputSteam用法类似
输出流 OutputStream类常用方法
int write (byte[] b,int off,int len)将指定字节数组从off位置开始的len字节的内容写入输出流close()关闭数据流,当完成对数据流的操作之后需要关闭数据流flush()刷新输出流,强行将缓冲区的内容写入输出流
在读取或写入IO流的过程中,可能会发生错误,例如,文件不存在导致无法读取,没有写权限导致写入失败,等等,这些底层错误由Java虚拟机自动封装成IOException异常并抛出。因此,所有与IO操作相关的代码都必须正确处理IOException。
字节输入流常用类
字节输入流/输出
输入:
ByteArrayInputStream类:将字节数组转换为字节输入流,从中读取字节。FileInputStream类:从文件中读取数据。PipedInputStream类:连接到一个 PipedOutputStream(管道输出流)。SequenceInputStream类:将多个字节输入流串联成一个字节输入流。ObjectInputStream类:将对象反序列化。
输出:
ByteArrayOutputStream类:向内存缓冲区的字节数组中写数据。FileOutputStream类:向文件中写数据。PipedOutputStream类:连接到一个 PipedlntputStream(管道输入流)。ObjectOutputStream类:将对象序列化。
字节数组输入流/输出
输入:
ByteArrayInputStream(byte[] buf, [int offse,int length]):创建一个字节数组输入流,其中,参数 buf 指定字节数组类型的数据源,offset 指定在数组中开始读取数据的起始下标位置,length 指定读取的元素个数。
输出:
ByteArrayOutputStream([int size]):创建一个字节数组输出流,输出流缓冲区的初始容量大小由参数 size 指定,初始容量大小为 32 字节。intsize():返回缓冲区中的当前字节数。byte[] toByteArray():以字节数组的形式返回输出流中的当前内容。
文件输入流/输出
-
FileInputStream输入是Java流中比较常用的一种,它表示从文件系统的某个文件中获取输入字节。通过使用FileInputStream可以访问文件中的一个字节、一批字节或整个文件。 -
FileOutputStream(File file | String name,[boolean append])输出 :通过打开一个到实际文件的链接来创建一个FileInputStream,file为文件系统中的 File 对象;name为文件系统中的路径名。append指定是否将数据添加到目标文件的内容末尾,如果为true,则在末尾添加。默认为false
字符输入流常用类
字符输入流/输出
输入:
CharArrayReader类:将字符数组转换为字符输入流,从中读取字符。StringReader类:将字符串转换为字符输入流,从中读取字符。BufferedReader类:为其他字符输入流提供读缓冲区。PipedReader类:连接到一个PipedWriter。InputStreamReader类:将字节输入流转换为字符输入流,可以指定字符编码。
输出:
CharArrayWriter类:向内存缓冲区的字符数组写数据。StringWriter类:向内存缓冲区的字符串(StringBuffer)写数据。BufferedWriter类:为其他字符输出流提供写缓冲区。PipedWriter类:连接到一个PipedReader。OutputStreamReader类:将字节输出流转换为字符输出流,可以指定字符编码
字符文件输入/输出流
输入:
FileReader(File file | String fileName):在给定要读取数据的文件的情况下创建一个新的FileReader对象。其中,file表示要从中读取数据的文件对象。fileName表示的是一个文件的完整路径
输出:
FileWriter(File file | String fileName, boolean append)写入数据,file和fileName同上,append的值为true,则将字节写入文件末尾,而不是写入文件开始处
FileWriter 类的创建不依赖于文件存在与否,如果关联文件不存在,则会自动生成一个新的文件。在创建文件之前,FileWriter 将在创建对象时打开它作为输出。如果试图打开一个只读文件,将引
字符缓冲区输入/输出流
输入:
BufferedReader(Reader in, [int size])创建一个BufferedReader来修饰参数 in 指定的字符输入流,参数 size 则用于指定缓冲区的大小,单位为字符 可选。
- 该类下除了字符输入流提供缓冲区的方法以外, 还有
readLine()方法获取行信息
输出:
BufferedWriter(Writer out,[int size])创建一个BufferedWriter来修饰参数out指定的字符输出流,参数size则用于指定缓冲区的大小,单位为字符。
- 该类下除了字符输出流提供缓冲区的方法以外, 还有
newLine()方法写入一个行分隔符
File类文件操作
创建File对象
new File(String path):如果 path 是实际存在的路径,则该 File 对象表示的是目录;如果 path 是文件名,则该 File 对象表示的是文件。new File(String path, String name):path 是路径名,name 是文件名。new File(File dir, String name):dir 是路径对象,name 是文件名。
File类的常用方法
| 方法 | 说明 |
|---|---|
boolean canRead() |
测试应用程序是否能从指定的文件中进行读取 |
boolean canWrite() |
测试应用程序是否能写当前文件 |
boolean delete() |
删除当前对象指定的文件 |
boolean exists() |
测试当前 File 是否存在 |
String getAbsolutePath() |
返回由该对象表示的文件的绝对路径名 |
String getName() |
返回表示当前对象的文件名或路径名(如果是路径,则返回最后一级子路径名) |
String getParent() |
返回当前 File 对象所对应目录(最后一级子目录)的父目录名 |
boolean isAbsolute() |
测试当前 File 对象表示的文件是否为一个绝对路径名。该方法消除了不同平台的差异,可以直接判断 file 对象是否为绝对路径。 在 UNIX/Linux/BSD 等系统上,如果路径名开头是一条斜线/,则表明该 File 对象对应一个绝对路径; 在 Windows 等系统上,如果路径开头是盘符,则说明它是一个绝对路径。 |
boolean isDirectory() |
测试当前 File 对象表示的文件是否为一个路径 |
boolean isFile() |
测试当前 File 对象表示的文件是否为一个“普通”文件 |
long lastModified() |
返回当前 File 对象表示的文件最后修改的时间 |
long length() |
返回当前 File 对象表示的文件长度 |
String[] list() |
返回当前 File 对象指定的路径文件列表 |
String[] list(Filter) |
返回当前 File 对象指定的目录中满足指定过滤器的文件列表 |
boolean mkdir() |
创建一个目录,它的路径名由当前 File 对象指定 |
boolean mkdirs() |
创建一个目录,它的路径名由当前 File 对象指定 |
boolean renameTo(File) |
将当前 File 对象指定的文件更名为给定参数 File 指定的路径名 |
操作练习
public static void main(String[] args) throws Exception{
String url = "D:/text/file";
File f = new File(url);
System.out.println(f.canRead()); // 文件是否可以读取
System.out.println(f.canWrite());// 文件是否可以写入
System.out.println(f.exists()); // 文件是否存在
System.out.println(f.getAbsolutePath()); // 返回文件的绝对路径
String[] fileList = f.list(); // 返回文件目录
System.out.println(Arrays.toString(fileList));
/**
* 创建文件对象
* abc.txt d的文件内容为:这是一个文件内容 Hello world
**/
File txt = new File(url,"abc.txt");
if(txt.exists()){// 如果文件存在
//创建文件输入流对象
FileInputStream fis = new FileInputStream(txt);
// 创建byte 类型的数组
byte[] bytes = new byte[1024];
int n = fis.read(bytes); // 返回读取的字节数
// 将字节转换为字符串
String str = new String(bytes,0,n);
System.out.println(str);
}
}
读取文件内容,并增加新内容,然后保存到另一个新文件中
import java.io.*;
import java.util.ArrayList;
public class Main {
public static String readUrl = "D:/mxx-project/myself/java-demos/file/abc.txt"; // 读取路径
public static String writeUrl = "D:/mxx-project/myself/java-demos/file/abcCopy.txt"; // 写入路径
public static ArrayList<String> alist = new ArrayList<String>(); // 存储数据
// 读取文件内容
public static void read() throws Exception{
String linStr = "";
FileReader newFe = new FileReader(readUrl);
// 创建缓冲区对象
BufferedReader bfr = new BufferedReader(newFe);
// 将读取的每行内容添加到 ArryList 集合中
while ((linStr = bfr.readLine()) != null){
alist.add(linStr);
}
newFe.close();
bfr.close();
System.out.println(alist);
}
public void modification(String str, int i) throws Exception{
try{
alist.add(i-1,str); // 向arrayList集合中增加内容
System.out.println(alist);
}catch (Exception e){
e.printStackTrace();
}
}
public void write() throws Exception{
FileWriter fw = new FileWriter(writeUrl); // 创建FileWriter对象
BufferedWriter bfr = new BufferedWriter(fw);
for(String str:alist){
bfr.write(str); // 向缓存区写入内容
bfr.newLine(); // 向缓存区写入分割符
}
bfr.flush(); //刷新输出流,强行将缓冲区的内容写入输出流
fw.close();
}
public static void main(String[] args) throws Exception{
Main m = new Main();
m.read();
m.modification("这是新增加的内容",2);
m.write();
}
}