IO文件流学习

创建文件,文件夹,获取文件数据,对象

package Chapter07;
// JAVA的标准库java.io提供了File对象来操作文件和目录。
import java.io.File;

public class Stream01 {
public static void main(String[] args) throws Exception{

// TODO Java IO - 文件流

// TODO File : 文件类型(文件,文件夹),属于java.io
// 创建文件对象, 使用文件路径关联系统文件
String filePath = "C:\\Users\\28902\\Desktop\\javas-speedLearn\\Data";
File file = new File(filePath);
System.out.println(file);
// 文件对象的操作
// // TODO 判断当前文件对象是否为文件
// System.out.println(file.isFile());
// // TODO 判断当前文件对象是否为文件夹
// System.out.println(file.isDirectory());
// // TODO 判断文件对象是否存在关联
// System.out.println(file.exists());

if ( file.exists() ) {
// TODO 文件对象存在的情况
System.out.println("文件对象存在");
if (file.isFile()) {
System.out.println("文件对象关联的是一个文件");
System.out.println(file.getName()); // 获取当前文件名
System.out.println(file.length()); // 获取当前文件的大小
System.out.println(file.lastModified()); // 获取当前文件的最后修改时间
System.out.println(file.getAbsolutePath()); // 获取当前文件的绝对路径
} else if ( file.isDirectory() ) {
System.out.println("文件对象关联的是一个文件夹");
System.out.println(file.getName()); // 获取当前文件夹名
System.out.println(file.lastModified()); // 获取当前文件夹的最后修改时间
System.out.println(file.getAbsolutePath()); // 获取当前文件夹的绝对路径
String[] list = file.list(); // 获取当前文件夹中的文件名
System.out.println("文件夹中的文件:");
for (String s : list) {
System.out.println(s); // 循环遍历输出当前文件夹中的文件名
}
System.out.println("文件夹中的文件对象:");
File[] files = file.listFiles(); // 获取文件对象
for (File s : files) {
System.out.println(s); // 遍历输出文件对象
}
}
} else {
// TODO 文件对象不存在的情况
System.out.println("文件对象不存在,没有关联成功");
// TODO 创建多级文件目录
// file.mkdirs(); // s结尾为可创建多级目录
// TODO 创建新文件
// file.createNewFile(); // 创建新的文件
}
}
}

文件复制 - (文件的读取操作)

package Chapter07;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; // 导入文件io异常

public class copy {
public static void main(String[] args){

// TODO Java IO - 文件复制

// TODO 数据源文件对象
File srcFile = new File("C:\\Users\\28902\\Desktop\\javas-speedLearn\\Data\\HelloWorld.txt");
// TODO 数据目的地文件对象(自动生成)
File destFilt = new File("C:\\Users\\28902\\Desktop\\javas-speedLearn\\Data\\HelloWorld.txt.copy");

// TODO 文件输入流(管道对象)
FileInputStream in = null;
// TODO 文件输出流(管道对象)
FileOutputStream out = null;
try {
in = new FileInputStream(srcFile);
out = new FileOutputStream(destFilt);

int data = -1; // 定义标志位,文件输出完毕

// TODO 打开阀门,流转数据(输入)
// data = in.read();

// TODO 打开阀门,流转数据(输出)
//out.write(data);

// TODO 问题1 : 代码重复性比较强
// TODO 问题2 : 多读数据
//
// // TODO 如果文件数据已经全部读取完毕后,那么再去读取数据,读取的结果就是-1,表示无效(结尾)
// data = in.read();
// if ( data != -1 ) {
// out.write(data);
// }
// //System.out.println(data);
// 阀门是传递一个数据关闭一次,因此我们要不断的开关阀门,直到最后读出来的数据为-1,表示数据传输完毕
while ( (data = in.read()) != -1 ) {
out.write(data);
// System.out.println(data); // 输出文件数据
}

} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 文件传输完毕后一点过要关闭文件输出口和文件输出口,相当于洗完手要关水龙头一样
if ( in != null ) { // 可能变空指针
try {
in.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if ( out != null ) {
try {
out.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}

// 结果: 成功复制了HelloWorld.txt的文件数据到HelloWorld.txt.copy(不存在则自动创建)中去

IO缓冲流(Buffer)

  • 由上面的文件复制操作,我们可以看出,文件数据传输的阀门默认一次只能传递一个字符,这样的话效率就太低了,如果一次可以传递多个数据,效率就会大大增加,由此可以引出IO缓冲流这一个概念,它可以让我们阀门打开一次传递多个数据
  • 实际愿原理就是在文件传输的过程中新增一个管道(buffer),数据流经buffer管道将会保存到缓冲区中去,最后在输出到另一个文件中去

image

package Chapter07;
import java.io.*;

public class copy_Buffer {
public static void main(String[] args){

// TODO Java IO - 文件复制 - 缓冲

// TODO 数据源文件对象
File srcFile = new File("C:\\Users\\28902\\Desktop\\javas-speedLearn\\Data\\HelloWorld.txt");
// TODO 数据目的地文件对象(自动生成)
File destFilt = new File("C:\\Users\\28902\\Desktop\\javas-speedLearn\\Data\\HelloWorld.txt.bufferCopy");

// TODO 文件输入流(管道对象)
FileInputStream in = null;
// TODO 文件输出流(管道对象)
FileOutputStream out = null;

// TODO 缓冲输入流(管道对象)
BufferedInputStream buffIn = null;
// TODO 缓冲输出流(管道对象)
BufferedOutputStream buffOut = null;

// TODO 缓冲区(水桶) 设置缓冲区大小
byte[] cache = new byte[1024];

try {
// 连接文件阀门入口
in = new FileInputStream(srcFile);
// 连接文件阀门出口
out = new FileOutputStream(destFilt);

// 连文件阀门入口接到buffer入口中去
buffIn = new BufferedInputStream(in);
// 连文件阀门出口接到buffer出口中去
buffOut = new BufferedOutputStream(out);

// TODO 打开阀门,流转数据(输入)
int data = -1;
// 判断关闭缓冲区的逻辑(即缓冲入口不再读取到数据,即=-1)
while ( (data = buffIn.read(cache)) != -1 ) {
// 将缓冲区的数据写入目标文件夹中(从0开始写,读取多少就写多少)
buffOut.write(cache, 0, data);
}

} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 文件传输完毕后一点过要关闭文件输出口和文件输出口,相当于洗完手要关水龙头一样
if ( buffIn != null ) {
try {
buffIn.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if ( buffOut != null ) {
try {
buffOut.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
// 同样可以成功生成并复制数据到目标文件(HelloWorld.txt.bufferCopy)

字符流(常用)

  • 与上面的例子相比,上面的例子是使用字节流传输数据的(输出的是字节),下面的字符流与字节流非常的相似,只不过传输的数据是以字符串的形式传递罢了

image

package Chapter07;
import java.io.*;

public class IO_String {
public static void main(String[] args){

// TODO Java IO - 文件复制 - 字符串

// TODO 数据源文件对象
File srcFile = new File("C:\\Users\\28902\\Desktop\\javas-speedLearn\\Data\\HelloWorld.txt");
// TODO 数据目的地文件对象(自动生成)
File destFilt = new File("C:\\Users\\28902\\Desktop\\javas-speedLearn\\Data\\HelloWorld.StringCopy.txt");

// TODO 字符输入流(管道对象)
BufferedReader reader = null; // buffer输入流对象
// TODO 字符输出流(管道对象)
PrintWriter writer = null; // 打印输出流对象,相较于buffer输出流更为简单(BufferWriter),效果是一样的
try {
// 接入文件输入口与输入文件
reader = new BufferedReader(new FileReader(srcFile));
// 接入文件输出口与输出文件
writer = new PrintWriter(destFilt);

// TODO 打开阀门,流转数据(输入)
// 读取文件中的一行数据(字符串),就不再是读取字节了
String line = null;

// 判断字符串的读写逻辑,不再读取到字符串说明文件读取完毕即为空null
while ( (line = reader.readLine()) != null ) {
System.out.println(line); // 输出读取到的文件数据
writer.println(line); // 文件写入
}
// 刷写数据(字符流要先刷新数据才能关闭阀门)
writer.flush();

} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 文件传输完毕后一点过要关闭文件输出口和文件输出口,相当于洗完手要关水龙头一样
if ( reader != null ) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if ( writer != null ) {
writer.close();
}
}
}
}
// 成功复制文件数据到目标文件中去