异常:
略。
File:
(1)构造:
- File(String pathname)
- File(String parent, String child)
- File(File parent, String child)
(2)方法:
- 创建
- public boolean createNewFile()
- public boolean mkdir()
- public boolean mkdirs()
- 删除
- public boolean delete()(注意:删除文件夹时 这个文件夹是空文件夹 如果这个文件夹里面有文件,则不能删除)
- public boolean renameTo(File dest) 把文件重命名为指定的文件路径(注意事项:
如果路径名相同,就是改名。
如果路径名不同,就是改名并剪切。) - 判断:
- public boolean isDirectory(): 判断是否是目录
- public boolean isFile(): 判断是否是文件
- public boolean exists()
- public boolean canRead()
- public boolean canWrite()
- public boolean isHidden()
- public boolean isAbsolute()
- 获取:
- public String getAbsolutePath():
- public String getPath(): 获取相对路径
- public String getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null(相对路径就会返null)
- public File getParentFile() 返父目录的File对象,没有指定的话同上。
- public long getTotalSpace()返回此抽象路径名指定的分区大小。 返回总容量 单位字节
- public long getFreeSpace() 返回此抽象路径名指定的分区中未分配的字节数。返回剩余容量 单位字节
- public String getName(): 获取名称
- public long length(): 获取长度。字节数
- public long lastModified(): 获取最后一次的修改时间,毫秒值
- public String[] list(): 获取指定目录下的所有文件或者文件夹的名称数组
- public File[] listFiles(): 获取指定目录下的所有文件或者文件夹的File数组
- public String[] list(FilenameFilter filter) (list方法重载,过滤器,重写方法)
- public File[] listFiles(FilenameFilter filter)
例如:
File file = new File("C:\\Users\\ShenMouMou\\Desktop\\test");
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
//System.out.println("过滤的方法执行了" + dir + "===" + name);
File file1 = new File(dir, name);
if (file1.isFile() && name.endsWith(".jpg")) {
return true;
}
//返回true 符合条件就会把文件过滤到文件数组中,返回false表示不符合条件,不会过滤到数组中
return false;
}
});
System.out.println(Arrays.toString(files));
IO流:
一、字节流:(任意类型)
抽象基类为:InputStream ,OutputStream
FileOutputStream:
(1)构造:
- FileOutputStream(File file)
- FileOutputStream(String name)
如果文件不存在会自动创建
(2)方法:
- public void write(int b)
- public void write(byte[] b)
- public void write(byte[] b,int off,int len)
- close()
FileInputStream:
(1)构造:
- 同上。但关联文件不存的在话,不会自动创建,会报错。
(2)方法:
- int read():一次读取一个字节,如果没有数据返回-1
- int read(byte[] b) :返回读取到的有效字节的长度
- int read(byte[] b, int off, int len)
例:复制文本对象:
//模板代码:
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
try {
//很显然一次读写一个字节,来进行文件的复制,效率太低,你应该一次读取一个字节数组,来进行复制。
in = new FileInputStream("C:\\Users\\ShenMouMou\\Music\\夜夜夜夜.mp3");
out = new FileOutputStream("E:\\夜2222.mp3");
//创建一个数组来充当缓冲区
byte[] bytes = new byte[1024 * 8];
//返回的是读取的到有效的字节个数
int len = 0; //定义一个变量,来接收每次读取到的有效的字节个数
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
System.out.println("正在复制...");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
System.out.println("复制完毕");
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedInputStream+BufferedOutputStream:
(1)构造:
- BufferedOutputStream(OutputStream out)
- BufferedInputStream(InputStream in)
- BufferedOutputStream(OutputStream out,int size)
- BufferedInputStream(InputStream in,int size)
底部维护了一个缓冲区,大小为8*1024,可以通过构造来改变大小。如果和普通的字节流都自己给出缓冲区大小,则区别不大。使用的时候最好都自己定义。
(2)方法同上。
二、字符流
字符流=字节流+编码表
OutputStreamWriter
如果关联文件不存在,就自动创建。
(1)构造
- OutputStreamWriter(OutputStream out):根据默认编码(GBK)把字节流的数据转换为字符流
- OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
(2)方法:
- public void write(int c) 写一个字符
- public void write(char[] cbuf) 写一个字符数组
- public void write(char[] cbuf,int off,int len) 写一个字符数组的 一部分
- public void write(String str) 写一个字符串
- public void write(String str,int off,int len) 写一个字符串的一部分
- flush() 字符流需要刷新一下
InputStreamReader:
同字节流,不自动创建关联文件。
(1)构造:
- InputStreamReader(InputStream is):用默认的编码(GBK)读取数据
- InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
(2)方法:
- public int read() 一次读取一个字符,如果没有读到 返回-1
- public int read(char[] cbuf) 一次读取一个字符数组 如果没有读到 返回-1 返回的是字符长度
例:
public static void main(String[] args) {
InputStreamReader reader = null;
OutputStreamWriter writer = null;
try {
reader = new InputStreamReader(new FileInputStream("MyTest.java"));
writer = new OutputStreamWriter(new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\MyTest2.java"));
//定义一个字符数组来充当缓冲区
char[] chars = new char[2000];
int len = 0; //记录每次读取到的有序的字符个数
while ((len = reader.read(chars)) != -1) {
writer.write(chars, 0, len);
writer.flush();
System.out.println("复制");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileReader+FileWriter:(字符便捷流)
- OutputStreamWriter ------- FileWriter
- InputStreamReader ------- FileReader
(1)构造:
- FileReader(File file)
- FileReader(String fileName)
(2)方法:继承父类
BufferedWriter+BufferedReader:(高效字符流)
(1)构造:
- public BufferedWriter(Writer w)
- public BufferedReader(Reader e)
(2)方法:
- read及其重载
BufferedReader reader = new BufferedReader(new FileReader("MyTest.java"));
//new BufferedWriter(new OutputStreamWriter(new FileOutputStream("MyTest3.java")));
BufferedWriter writer = new BufferedWriter(new FileWriter("myTest3.java"));
char[] chars = new char[2000];
int len = 0; //记录每次读取到的有序的字符个数
while ((len = reader.read(chars)) != -1) {
writer.write(chars, 0, len);
writer.flush();
System.out.println("复制");
}
reader.close();
writer.close();
- 特有方法:
- public void newLine() 根据系统来调用对应的换行符
- public String readLine() 一次读取一行数据 没读到数据返回null
三、其余流:
(1)DataInputStream+DataOutputStream(数据输入输出流):
读写基本数据类型。
构造:
- DataInputStream(InputStream in)
- DataOutputStream(OutputStream in)
方法:
- read***()
- write***()
例:
//注意:按照类型进行读写,顺序一致。
DataOutputStream ds = new DataOutputStream(new FileOutputStream("a.txt"));
ds.writeInt(500);
ds.writeBoolean(true);
ds.writeUTF("hahaha");
ds.writeDouble(3.14);
ds.close();
DataInputStream in = new DataInputStream(new FileInputStream("a.txt"));
int num = in.readInt();
System.out.println(num);
boolean b = in.readBoolean();
System.out.println(b);
String s = in.readUTF();
System.out.println(s);
double v = in.readDouble();
System.out.println(v);
(2)ByteArrayOutputStream+ByteArrayInputStream(内存操作流)
不会关联文件,只是在内存中进行数据的读写,内存操作流,会自己在内存中维护了一个缓存,把数据维护在缓存中,此流无需关闭。
构造:
- ByteArrayOutputStream()
- ByteArrayInputStream( byte[] buf) (buf作为内存维护的要读的缓冲区数组)
方法:
- toByteArray ()
- toString ()
- read(byte[] bytes)
/* 此类实现了一个输出流,其中的数据被写入一个 byte 数组。
缓冲区会随着数据的不断写入而自动增长。
可使用 toByteArray () 和 toString () 获取数据。
关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
*/
/* 构造方法摘要
ByteArrayOutputStream()
创建一个新的 byte 数组输出流。
*/
//自己在内存中维护了一个字节数组充当缓存,你用他写入的数据,就会放到他维护的这个字节数组中, 缓冲区会随着数据的不断写入而自动增长
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("aaa".getBytes());
bos.write("bbb".getBytes());
bos.write("ccc".getBytes());
//取出ByteArrayOutputStream 他所维护的那个字节数组
byte[] bytes = bos.toByteArray();
String s = new String(bytes);
// System.out.println(s);
//如果放的是,字符串的字节数据,你可以直接调用toString()
String s2 = bos.toString();
System.out.println(s2);
byte[] bytes = "西部开源教育科技有限公司".getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
byte[] bytes1 = new byte[1024];
int len = in.read(bytes1);
String s = new String(bytes1, 0, len);
System.out.println(s);
案例:歌曲大联唱
public static void main(String[] args) throws IOException {
FileInputStream in1 = new FileInputStream("许巍 - 蓝莲花.mp3");
FileInputStream in2 = new FileInputStream("许巍 - 曾经的你.mp3");
FileOutputStream allOut = new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\歌曲大连唱2.mp3");
ArrayList<FileInputStream> list = new ArrayList<>();
list.add(in1);
list.add(in2);
byte[] bytes2 = new byte[1024 * 8];
int len2 = 0;
for (FileInputStream in : list) {
while ((len2 = in.read(bytes2)) != -1) {
allOut.write(bytes2, 0, len2);
allOut.flush();
}
in.close();
}
allOut.close();
}
(3)CharArrayWrite-CharArrayReader:
(4)StringWriter-StringReader
略。
(5)打印流:PrintStream(字节)-PrintWriter(字符)
(1)构造:
- Print****(File file)
- Print****(String fileName)
- Print****(OutputStream out, boolean autoFlush) 创建带自动刷新的打印流 ,针对 println、printf 或 format 才有用
- PrintWriter(Writer out)
- PrintWriter(Writer out,boolean autoFlush)
public static void main(String[] args) throws IOException {
//打印流:只能写,不是成对的,只有一个
//字符打印流 PrintWriter
//字节打印流 PrintStream
//自己创建出来的打印流,关联的是文件,所以你在调用println("abc"); 会输出到文件中
PrintStream printStream = new PrintStream("e.txt");
printStream.write("你好".getBytes());
printStream.println("abc");
printStream.println(100);
printStream.println(3.14);
//out “标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器
//System.out; 获取出的PrintStream 他所关联的设备是屏幕,所以你打印的数据,就会输出到屏幕上。
PrintStream out = System.out;
out.println(200);
out.write("hahah".getBytes());
}
(6)RandomAccessFile
能读能写,可以获取文件指针。注意:怎么写的就怎么读,按顺序。
构造:
- RandomAccessFile(File file, String mode)
方法:
- read***()
- -write***()
- getFilePointer() 获取文件指针的位置
- seek(int) 设置文件指针的位置
注意:写汉字会多写两个字节进去。
public static void main(String[] args) throws IOException {
//RandomAccessFile 这个流最大的特点,有文件指针指针,可以进行断点,还有一个就是能读能写
//此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;
// RandomAccessFile(File file, String mode)
// 创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
//你怎么写的你就怎么读,顺序不要乱
RandomAccessFile in = new RandomAccessFile(new File("a.txt"), "rw");
boolean b = in.readBoolean();
//获取文件指针的位置
long filePointer = in.getFilePointer();
System.out.println(filePointer); //1
double v = in.readDouble();
filePointer = in.getFilePointer();
System.out.println(filePointer); //9
int i = in.readInt();
filePointer = in.getFilePointer();
System.out.println(filePointer); //13
String s = in.readUTF();
filePointer = in.getFilePointer();
System.out.println(filePointer); //21
//设置文件的指针位置
in.seek(13);
s = in.readUTF();
System.out.println(s);
System.out.println(b);
System.out.println(v);
System.out.println(i);
System.out.println(s);
}
private static void writeData() throws IOException {
RandomAccessFile out = new RandomAccessFile(new File("a.txt"), "rw");
out.writeBoolean(false);
out.writeDouble(3.14);
out.writeInt(100);
/* 写汉字会多写两个字节进去*/
out.writeUTF("呵呵");
out.close();
}
案例:断点复制(先将断点的文件指针的位置信息获取到配置文件中)
public static void main(String[] args) throws IOException {
//模拟断点复制
File file = new File("歌曲大连唱2.mp3");
File file2 = new File("C:\\Users\\ShenMouMou\\Desktop\\歌曲大连唱333.mp3");
RandomAccessFile in = new RandomAccessFile(file, "rw");
RandomAccessFile out = new RandomAccessFile(file2, "rw");
//继续:判断目标文件是否还存在,如果不存在,就从头复制,如果存在,获取上次记录的断点的位置,继续复制
if (!file2.exists()) {
in.seek(0);
out.seek(0);
}
//如果文件存在,就从上次的断点位置,开始复制
//读取上次的断点位置
BufferedReader reader = new BufferedReader(new FileReader("config.txt"));
String seek = reader.readLine();
//设置从哪个位置开始复制。
in.seek(Long.parseLong(seek));
out.seek(Long.parseLong(seek));
byte[] bytes = new byte[1];
int len = 0;
int i = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
//模拟暂停
/* i = i += 2;
if (i > 100000) {
//获取暂停后文件的指针位置
long filePointer = in.getFilePointer();
//把这个文件指针的位置,保存到一个配置文件里面
PrintWriter pw = new PrintWriter(new FileOutputStream("config.txt"), true);
pw.println(filePointer);
break;
}*/
}
in.close();
out.close();
}
(7)ObjectOutputStream-ObjectInputStream(序列化流与反序列化流):
流的形式存储到文件-------对象
类需要实现Serializable接口(标记接口,里面没有任何方法)
构造:
- ObjectOutputStream(OutputStream out)
- ObjectInputStream(InputStream out)
方法:
- readObject() (返回Object类,再向下转型)
- writeObject()
反序列化的时候,会验证标记。手动给出标记。
- private static final long serialVersionUID
阻止成员序列化:
- transient
(8)Properties :
继承Hashtable,键值都是字符串,泛型已指定。
配置文件键值:= 拼接,后缀名.p roperties
构造:
- Properties()
方法:
- 父类put,get
- 特有:
- public Object setProperty(String key,String value)
- public String getProperty(String key)
- public String getProperty(String key,defaultValue str) (如果找不到键值,就返回defaultValue)
- public Set stringPropertyNames()
- public void store(W/I writer, String comments)把Properties集合中的键值对数据写入到文件中, comments注释
- public void load(R/O reader): 读取键值对数据把数据存储到Properties中
(9)SequenceInputStream:
将流串起来。
构造:
- SequenceInputStream(InputStream s1, InputStream s2)
- SequenceInputStream(Enumeration<? extends InputStream> e) (迭代合并多个流)
public static void main(String[] args) throws FileNotFoundException {
/* SequenceInputStream(Enumeration < ? extends InputStream > e)
通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。*/
FileInputStream in = new FileInputStream("user.properties");
FileInputStream in2 = new FileInputStream("user2.properties");
FileInputStream in3 = new FileInputStream("user2.properties");
Vector<FileInputStream> vector = new Vector<>();
vector.add(in);
vector.add(in2);
vector.add(in3);
Enumeration<FileInputStream> elements = vector.elements();
SequenceInputStream allIn = new SequenceInputStream(elements);
}