首先放复制多级文件夹的程序:
public static void main(String[] args) throws IOException {
//复制单级文件夹并该后缀名
//1.封装源文件夹
File srcFolder = new File("D:\\test");
//2.封装目标文件夹
File targetFolder = new File("E:\\test");
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
//复制文件夹
copyFolder(srcFolder, targetFolder);
System.out.println("复制完成!");
}
private static void copyFolder(File srcFolder, File targetFolder) throws IOException {
//获取源文件夹下所有的文件,复制并改名
File[] files = srcFolder.listFiles();
for (File f : files) {
if (f.isFile()) {
copyFiles(f, targetFolder);
} else {
//如果说是文件夹怎么办?
//封装源文件夹 f
//封装目标文件夹
File sonTargetFolder = new File(targetFolder + "\\" + f.getName());
if (!sonTargetFolder.exists()) {
sonTargetFolder.mkdirs();
}
//递归调用
copyFolder(f, sonTargetFolder);
}
}
}
删除多级目录
private static void copyFiles(File f, File targetFolder) throws IOException {
// System.out.println(targetFolder + "\\" + f.getName());
//读取源文件
FileInputStream in = new FileInputStream(f);
FileOutputStream out = new FileOutputStream(targetFolder + "\\" + f.getName());
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
in.close();
out.close();
}
public static void main(String[] args) {
//删除多级目录
File file = new File("E:\\demo");
deleteFolder(file);
}
private static void deleteFolder(File file) {
//获取此目录下所有的文件或者目录
File[] files = file.listFiles();
for (File f : files) {
if (f.isFile()) {
f.delete();
} else {
deleteFolder(f);
}
}
file.delete();//删除自身这个空文件夹
}
}
IO流基类概述
A:IO流基类概述
a:字节流的抽象基类:
InputStream ,OutputStream。
b:字符流的抽象基类:
Reader , Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
Io流
FileOutputStream的三个write()方法
public void write(int b):写一个字节 超过一个字节 砍掉前面的字节
public void write(byte[] b):写一个字节数组
public void write(byte[] b,int off,int len):写一个字节数组的一部分
文件输出流,所关联的文件,如果不存在,会帮你自动创建
FileOutputStream写出数据如何实现数据的换行
windows下的换行符只用是 \r\n
Linux \n
Mac \r
FileOutputStream写出数据如何实现数据的追加写入
FileOutputStream fos = new FileOutputStream(“fos.txt” , true) ; // 完成追加写入
流使用完之后记得关闭。
流的异常处理
FileOutputStream out = null;
try {
System.out.println(1 / 0);
out = new FileOutputStream("e.txt");
out.write(100);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
读写一体
FileInputStream in = new FileInputStream("D:\\夜夜夜夜.mp3");
FileOutputStream out = new FileOutputStream("E:\\夜夜夜夜.mp3");
//创建一个字节数组,充当缓冲区
byte[] bytes = new byte[1024 * 8];
//定义一个变量,记录每次读取到的有效字节个数
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
in.close();
out.close();
}
字节流异常捕获
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("D:\\夜夜夜夜.mp3");
out = new FileOutputStream("E:\\\\夜夜夜夜.mp3");
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();//刷新缓冲区
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
高效的字节输入输出流
BufferedInputStream(InputStream in, int size)
BufferedOutputStream(OutputStream in, int size)
它们的不同在于有一个自带的内部缓冲区数组,大小可以自己定。
字符流
字符流,是为了方便我们读写文本文件,在换句话说,字符流只能读写文本文件,其他类型的文件读写不了。
基本格式是这样的:OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(“a.txt”));
创建使用默认字符编码的 OutputStreamWriter。
out.flush();//注意:字符流要刷新一下,才会将缓存中的数据,写入到硬盘。
将一个字符串转换成字节数组
编码:把看的懂,转成看不懂的
解码:把看不懂,转成看的懂得
乱码产生的原因:编解码使用的不是同一个码表
换句话说,就是字符串编码之后变成机器语言,我们看不懂Jvm看的懂,编码跟解码要一个表,“不能拿前朝的剑斩本朝的官”!
byte[] bytes = “切格瓦拉酱”.getBytes(“UTF-8”);
将字符串变成字节数组然后再写入,期间可以指定码表。
基本说完之后就是复制文本了,一样的套路,不一样的只是字节数组变为字符数组:
InputStreamReader in = new InputStreamReader(new FileInputStream("MyTest.java"));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("E:\\MyTest.java"));
int len = 0;
char[] chars = new char[1024];
while ((len = in.read(chars)) != -1) {
out.write(chars, 0, len);
out.flush();
}
//释放资源
in.close();
out.close();
}
这里要提一下它这个字符数组的大小跟你复制完了之后数据丢失没有关系,它只是一个容器,大了Jvm少来几次,小了多来几次一样。
字符流的便捷形式
父类 子类 (便捷类)
OutputStreamWriter--------FileWriter
InputStreamReader---------FileReader
看到Java这么贴心我都快哭了?,怕记不住吗?
FileReader fileReader = new FileReader("MyTest.java");
FileWriter fileWriter = new FileWriter("E:\\MyTest2.java");
int len = 0;
char[] chars = new char[1024];
while ((len = fileReader.read(chars)) != -1) {
fileWriter.write(chars, 0, len);
fileWriter.flush();
}
fileReader.close();
fileWriter.close();
效果一样。
高效的字符流
BufferedReader in = new BufferedReader(new FileReader("MyTest.java"));
BufferedWriter out = new BufferedWriter(new FileWriter("E:\\MyTest3.java"));
int len = 0;
char[] chars = new char[1024];
while ((len = in.read(chars)) != -1) {
out.write(chars, 0, len);
out.flush();
}
//释放资源
in.close();
out.close();
跟上面一样,只是它有特有的方法可以用
//BufferedWriter 里面有一个特有的方法 void newLine () 写入一个换行符,具有平台兼容性
BufferedWriter out = new BufferedWriter(new FileWriter("E:\\MyTest4.java"));
//采用读取一行写人一行来复制文件
String line = null;
while ((line = in.readLine()) != null) { //读取不到返回 null
out.write(line);
out.newLine();
out.flush();
}
in.close();
out.close();
}
接下来就是将集合中的字符串写入文本以及Scanner输入流,直接放代码了:
ArrayList<String> list = new ArrayList<>();
list.add("张飞");
list.add("赵云");
//遍历集合,取出数据,写入文本文件
BufferedWriter out = new BufferedWriter(new FileWriter("name.txt"));
for (String s : list) {
//System.out.println(s);
out.write(s);
out.newLine();
//out.write("\r\n");
out.flush();
}
out.close();
反过来读也一样
给你一个文本文件,把文本文件中的数据读取到ArrayList集合里面
BufferedReader in = new BufferedReader(new FileReader("name.txt"));
ArrayList<String> list = new ArrayList<>();
String line = null;
while ((line = in.readLine()) != null) {
list.add(line);
}
System.out.println(list);
}
}
方法就是先遍历集合,将其中对象拿出然后直接写。
当然IO流记得抛异常。
Scanner流
//InputStream in = System.in;
//Scanner(InputStream source)
//构造一个新的 Scanner,它生成的值是从指定的输入流扫描的。
ArrayList<String> strings = new ArrayList<>();
Scanner scanner = new Scanner(new FileInputStream("name.txt"));
while (scanner.hasNextLine()) {
String s = scanner.nextLine();
strings.add(s);
}
System.out.println(strings);
//Scanner(File source)
//构造一个新的 Scanner,它生成的值是从指定文件扫描的。
Scanner scanner1 = new Scanner(new File("name.txt"));
String s = scanner1.nextLine();
System.out.println(s);
字符流的好处我想了好久,就是无论你读或者写,你的对象都会以字符串形式出现,也就是我们本身自己可以直接看到文本中的东西,很直观?
~~基本类型 大小(字节)
byte 1
short 2
char 2~
int 4
long 8
float 4
double 8
boolean - (无)
~~