@[TOC]IO流3
① Apache IO包
- 简介
- JDK提供的文件相关的操作的类功能都很基础,在进行复杂操作时需要进行大量的编程工作。
Apache-commons工具包提供了IOUtils/FileUtils,可以更方便的对文件和目录进行操作。- Apache软件基金会(Apache Software Foundation,ASF)是专门为9支持开源软件项目而办的一个非盈利性组织。
官网为:www.apache.org- 很多著名的Java开源项目都来源于Apache。例如:commons、kafka、luncene、maven、shiro、struts等技术,以及大数据中的hadoop、hbase、spark、storm、mahout等。
- 下载commons io包
- 下载地址:https://commons.apache.org/proper/commons-io/download_io.cgi
- 添加方法:
选择项目结构
选择Libraries
选择jar包并添加
- FileUtils的使用
方法 | 说明 |
---|---|
static void cleanDirectory(File directory) | 清空目录,但是不删除目录(把目录包含的内容删除掉) |
static boolean contentEquals(File file1, File file2) | 比较两个文件是否相同 |
static void copyDirectory(File srcDir, File destDir) | 将个目录的内容拷贝到另一个目录 |
static void copyFile(File srcFile, File destFile) | 将文件拷贝到一个新的地址 |
static void copyFileToDirectory(File srcFile, File destDir) | 将一个文件拷贝到指定目录下 |
static void copyInputStreamToFile(InputStream source, File destination) | 将一个输入流中的文件拷贝到某个文件 |
static void deleteDirectory(File directory) | 删除目录 |
static boolean deleteQuietly(File file) | 删除文件 |
static Collection listFiles(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter) | 列出指定目录下的所有文件 |
static FileInputStream openInputStream(File file) | 打开指定文件的输入流 |
static FileOutputStream openOutputStream(File file) | 打开指定文件的输出流 |
static String readFileToString(File file) | 将文件内容作为字符串返回 |
static List readLines(File file) | 将文件内容按行返回到一个字符串数组中 |
static long sizeOf(File file) | 返回文件或目录的大小 |
static void write(File file, CharSequence data, boolean append) | 将字符串内容直接写到文件中 |
static void writeByteArrayToFile(File file, byte[] data) | 将字节数组内容写到文件中 |
static void writeLines(File file, Collection<?> lines) | 将容器元素的toString方法返回的内容依次写到文件中 |
static void writeStringToFile(File file, String data) | 将字符串写到文件当中 |
实现用String获取指定文件内容,并输出
import org.apache.commons.io.FileUtils;
import java.io.File;
public class FileUtilsDemo1 {
public static void main(String[] args) throws Exception{
String content = FileUtils.readFileToString(
new File("C:\\Users\\iFinder\\Desktop\\Java Learnning\\JavaSE\\src\\com\\IOLearning\\LongText.txt"), //指定文件路径
"utf-8"); //指定编码形式
System.out.println(content); //结果会作为一个String对象直接返回
}
}
实现将指定目录中的指定文件拷贝到目标目录中
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileFilter;
public class FileUtilsDemo2 {
public static void main(String[] args) throws Exception{
FileUtils.copyDirectory(
new File(""), //源目录路径
new File(""), //目标目录路径
new FileFilter() { //new一个接口的时候需通过匿名内部类实现接口的抽象方法
//在文件拷贝时的过滤条件,每拷贝一次文件都需要调用一次accept方法 true-拷贝
//pathname拷贝时的文件对象
@Override
public boolean accept(File pathname) {
if(pathname.isDirectory() || pathname.getName().endsWith("html")/*后缀*/){ //拷贝的条件
return true;
}
return false;
}
});
}
}
- IOUtils的使用
- IOUtils包中的很多方法都是重载的,理解起来比较方便
方法 | 说明 |
---|---|
static BufferedInputStream buffer(InputStream inputStream, int size) | 将传入的流进行包装,变成缓冲流,可以通过参数定义缓冲区大小 |
static void closeQuietly(Closeable closeable) | 关闭流的方法 |
static boolean contentEquals(Reader input1, Reader input2) | 比较两个流中的内容是否一致 |
static void copy(InputStream input, Writer output, Charset inputCharset) | 将输入流中的内容拷贝到输出流中,并且可以指定字符编码 |
static long copyLarge(InputStream input, OutputStream output) | 与copy相仿的方法,适合大于2G的内容的拷贝 |
static LineIterator lineIterator(InputStream input, String charsetName) | 返回一个可以迭代每一行内容的迭代器 |
static int read(InputStream input, byte[] buffer, int offset, int length) | 将输入流中的部分内容读到字节数组中 |
static void readFully(InputStream input, byte[] buffer) | 将输入流中的所有内容读到字节数组中 |
static List readLines(InputStream input, String charsetName) | 读取输入流内容中的一行 |
static InputStream toBufferedInputStream(InputStream input, int size) | 将输入转换为带缓存的输入流 |
static BufferedReader toBufferedReader(Reader reader, int size) | 将输入转换为带缓存的输入流 |
static byte[] toByteArray(InputStream input, int size) | 将内容转化为字节数组 |
static char[] toCharArray(InputStream is, String charsetName) | 将内容转化为字符数组 |
static String toString(byte[] input, String charsetName) | 将输入流或者数组中的内容转化为字符串 |
static void write(byte[] data, Writer output, String charsetName) | 向流中写内容 |
static void writeLines(Collection<?> lines, String lineEnding, OutputStream output) | 向流中写入一行或多行数据 |
import org.apache.commons.io.IOUtils;
import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
public class IOUtilsDemo {
public static void main(String[] args) throws Exception{
String content = IOUtils.toString(new FileInputStream("C:\\Users\\iFinder\\Desktop\\Java Learnning\\JavaSE\\src\\com\\IOLearning\\LongText.txt")
, StandardCharsets.UTF_8); //以什么样的规则进行转码
System.out.println(content);
}
}
② 随机访问流
- RandomAccessFile并不在JavaIO的四大类中
它可以实现两个作用:
实现对一个文件的做读与写的操作
可以访问文件的任意位置。不像其它流,必须先后进行读取。- 在开发某些客户端软件时,经常用到随机访问流“操作任意的文件”,比如,软件的使用次数与使用的日期,可以通过随机访问流对软件启动次数与日期做修改。
- 学习随机访问流需掌握3个核心方法
方法 | 说明 |
---|---|
RandomAccessFile(String name, String mode) | name用来确定路径,mode确定访问权限,r-读,rw-读 写 |
seek(long a) | 用来定位读写文件的位置,a确定读写位置与文件开头的字节个数 |
getFilePointer() | 获得流当前的读写位置 |
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile("E:/RadTest.txt","rw");
//写一些数据到文件中
int[] arr = new int[]{10,20,30,40,50,60,70,80};
for(int i:arr){
raf.writeInt(i);
}
//可以随机读取数据
raf.seek(4); //int占四个字节,标识跳过了arr中的第一条数据(让指针移动四下)
/*
* int[]{ 10 , 20 ,90,100,567,50,60,89};
* 0 1 2 3 4 5 6 7
* */
System.out.println(raf.readInt());
//可控制隔列读取数据
for (int i = 0; i < 8; i += 2) { //控制输出0,2,4,6,8个元素
raf.seek(i*4);
System.out.print(raf.readInt() + " "); //10 30 50 70
}
System.out.println();
//替换数组中某个位置的数据
raf.seek(8); //在第8字节的地方替换
raf.writeInt(45);
raf.seek(0);
for (int i = 0; i < 8; i ++) { //控制输出0,2,4,6,8个元素
System.out.print(raf.readInt() + " "); //10 20 45 40 50 60 70 80
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try{
if(raf != null){
raf.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
③File类在IO中的作用
- 当以文件作为数据源或者目标的时候,除了用字符串“C:/Test.txt”指定位置外,也可以用File类进行指定。
import java.io.*;
public class FileInIoDemo {
public static void main(String[] args) {
//用字符流读文件并添加行号
BufferedReader br = null;
BufferedWriter bw = null;
try{
//一般写法
//br = new BufferedReader(new FileReader("E:/text"));
//用File类指定
File fIn = new File("C:\\Users\\iFinder\\Desktop\\Java Learnning\\JavaSE\\src\\com\\IOLearning\\LongText.txt");
File fOut = new File("C:\\Users\\iFinder\\Desktop\\Java Learnning\\JavaSE\\src\\com\\IOLearning\\FileIO.txt");
br = new BufferedReader(new FileReader(fIn));
bw = new BufferedWriter(new FileWriter(fOut));
//整行读取加行号输出
String temp = "";
int i = 1;
while((temp = br.readLine()) != null){
bw.write(i + "\t" + temp);
bw.newLine();
i++;
}
bw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(br != null){
br.close();
}
if(bw != null){
bw.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
② IO流总结
- 按照流的方向分类:
输入流:数据源到程序(InputStream、Reader→读进来)
输出流:程序到目的地(OutputStream、Writer→写出去)- 按流的处理数据来分:
字节流:以字节为单元处理数据(InputStream、OutputStream)
字符流:以字符为单元处理数据(Reader、Writer)- 按照流的功能分类:
节点流:可以直接从数据源或目的地读写数据的流
处理流:不直接链接到数据源或者目的地,是处理其它流的流。通过对其它流的处理,提高程序的性能。- IO的四个基本抽象类:InputStream、OutputStream、Reader、Writer
- InputStream的实现类:
FileIputStream:文件字节输入流
ByteArrayInputStream:字节数组的字节输入流
BufferedInputStream:字节缓冲输入流(处理流)
DataInputStream:数据字节输入流
ObjectInputStream:对象字节输入流- OutputStream的实现类:
FileOutputStream:文件字节输出流
ByteArrayOutputStream:字节数组输出流
BufferedOutputStream:字节缓冲输出流(处理流)
DataOutputStream:数据字节输出流
ObjectOutputStream:对象字节输出流
printStream:字节输出流- Reader的实现类:
FileReader:文件的字符输入流
BufferedReader:字符缓冲输入流(处理流)
InputStreamReader:字节流转字符流的输入流(转换流)- Writer的实现类:
FileWriter:文件的字符输出流
BufferedWriter:字符缓冲输出流(处理流)
OutputStreamWriter:字节流转字符流的输出流(转换流)- 序列化与反序列化:
序列化:对象→字节序列
反序列化:字节序列→对象
要实现序列与反序列化的对象要实现Serializable接口