本篇文章主要是通过案例实现一些常见的需求来对IO知识进行整理:
文件流概览 |
这里不再介绍流
的概念,直接上菜
字节流和字符流的区别:
- 字节流操作的基本单元是字节,而字符流操作的基本单元是Unicode码元。
- 字节流操作的是文件本身,没有使用到缓冲区(可以简单理解为一段内存区域)。而字符流使用到了缓冲区,通过缓冲区操作文件(这个后面可以写个案列进行说明)
- 字节流通常用于处理二进制数据,实际上可以处理任意类型的数据。但是它不支持直接读写Unicode码元。字符流通常用于处理文本数据。
用字节流好还是字符流好?
两者相比较而言,字节流更加的通用,硬盘上的文件都是以字节的形式进行存储和传输,而字符只会在内存中才会形成,字符数组、字符串。在开发中,字节流的应用更加广泛。
需求案例 |
需求1:创建一个新的文件
/**
* 新建文件
*/
@Test
void test1() {
//直接在D盘下新建文件
String fileName = "D:" + File.separator + "Hello.txt";
//如果需要在指定的文件夹 upload 中创建文件
//String fileName = "D:" + File.separator +upload+File.separator+ "Hello.txt";
System.out.println(fileName);
File file = new File(fileName);
try {
file.createNewFile();
System.out.println("已创建了新文件");
} catch (IOException e) {
e.printStackTrace();
}
}
需求2:删除文件
/**
* 删除文件
*/
@Test
void test2() {
String fileName = "D:" + File.separator + "Hello.txt";
File file = new File(fileName);
if (file.exists()) {
file.delete();
System.out.println("删除了该文件");
} else {
System.out.println("该文件不存在");
}
}
需求3:创建一个新的文件夹
/**
* 创建一个文件夹
*/
@Test
void test3() {
String fileName = "D:" + File.separator + "Java";
File file = new File(fileName);
if (!file.exists()) {
file.mkdirs();
System.out.println("创建了文件夹");
} else {
System.out.println("已经存在该文件夹");
}
}
需求4:删除文件夹
/**
* 删除一个文件夹
*/
@Test
void test4() {
String fileName = "D:" + File.separator + "Java";
File file = new File(fileName);
if (file.exists()) {
file.delete();
System.out.println("删除了文件夹");
} else {
System.out.println("该文件夹不存在");
}
}
需求5:字节流-----向文件中写入字符串
/**
* 向文件中写入字符串
*/
@Test
void test5() throws IOException {
File file = new File("E:" + File.separator + "Hello.txt");
if (file.exists()) {
//如果文件存在,则向该文件中写入内容(直接覆盖文件中以前的内容)
FileOutputStream fileOutputStream = new FileOutputStream(file);
//如果希望是向文件中追加内容
// FileOutputStream fileOutputStream1 = new FileOutputStream(file, true);
String str = "这里是向文件中写入的内容";
byte[] bytes = str.getBytes();
fileOutputStream.write(bytes);
fileOutputStream.close();
System.out.println("写入内容成功");
} else {
System.out.println("不存在该文件");
}
}
需求6:字节流-----读取文件内容
使用字节流读取内容的时候,这里记录了两种方式,最主要的区别就是方式一
中,我们预先申请了一个指定大小的内存空间,但是这个空间在实际使用的过程中,可能会存在偏大或者偏小的情况,所以提倡使用方式二
。这样就可以精确大小了。
/**
* 读取文件内容
*/
@Test
void test6() throws IOException {
File file = new File("E:" + File.separator + "Hello.txt");
if(file.exists()){
FileInputStream inputStream = new FileInputStream(file);
//方式一:
/*byte[] bytes = new byte[1024];
inputStream.read(bytes);
System.out.println(new String(bytes));*/
//方式二:
byte[] bytes = new byte[(int) file.length()];
inputStream.read(bytes);
System.out.println(new String(bytes,0,(int)file.length()));
}else{
System.out.println("指定路径不存在此文件");
}
}
需求7:字符流-----向文件写入字符串
/**
* 字符流---向文件写入字符串
*/
@Test
void test7() throws IOException {
String name = "D:" + File.separator + "Hello.txt";
File file = new File(name);
FileWriter fileWriter = new FileWriter(file, true);
fileWriter.write("中国");
fileWriter.close();
System.out.println("写入文件成功");
}
需求8:字符流-----读取文件内容
/**
* 字符流
* <p>
* 读取文件
*/
@Test
void test8() throws IOException {
String name = "D:" + File.separator + "Hello.txt";
File file = new File(name);
FileReader fileReader = new FileReader(file);
char[] chars = new char[(int) file.length()];
int read = fileReader.read(chars);
fileReader.close();
System.out.println(new String(chars,0,read));
}
文章开头部分在介绍字节流和字符流的时候,提到了两者对于缓冲区的使用情况,这里可以分别在使用字节流和字符流向文件写入字符串的时候,将.close
关闭流的方法注释掉,然后再区分别读取两种方式的写入情况然后会发现:使用字节流的方式是成功将内容写入了,但是使用字符流的方式的时候,内容就没有写入成功,这就是因为字节流直接操作了文件本身,但是字符流是操作的缓冲区
需求9:合并文件内容
/**
* 合并文件内容
* <p>
* 将MyWorld.txt和Hello.txt中的内容合并到 merge.txt文件中
*/
@Test
void test9() throws IOException {
String name1 = "D:" + File.separator + "MyWorld.txt";
String name2 = "D:" + File.separator + "Hello.txt";
String name3 = "D:" + File.separator + "Merge.txt";
FileInputStream inputStream1 = new FileInputStream(name1);
FileInputStream inputStream2 = new FileInputStream(name2);
FileOutputStream fileOutputStream = new FileOutputStream(name3);
//合并流
SequenceInputStream sequenceInputStream = new SequenceInputStream(inputStream1, inputStream2);
//循环写入,如果读到文件的末尾,返回-1,如果没有返回-1,说明文件没有读完,继续读,然后写入merge.txt文件中
int temp = 0;
while ((temp = sequenceInputStream.read()) != -1) {
fileOutputStream.write(temp);
}
//关闭流
inputStream1.close();
inputStream2.close();
fileOutputStream.close();
sequenceInputStream.close();
}
需求10:压缩文件
/**
* 压缩文件
*
* @throws Exception
*/
@Test
void test10() throws Exception {
File file1 = new File("D:" + File.separator + "Hello.txt");
File file2 = new File("D:" + File.separator + "ZipFile.zip");
FileInputStream inputStream = new FileInputStream(file1);
FileOutputStream fileOutputStream = new FileOutputStream(file2);
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
zipOutputStream.putNextEntry(new ZipEntry(file1.getName()));
//设置注释
zipOutputStream.setComment("hello,world!");
int temp;
while ((temp = inputStream.read()) != -1) {
zipOutputStream.write(temp);
}
inputStream.close();
zipOutputStream.close();
}
需求11:解压缩单个文件
/**
* 解压缩单个文件
*/
@Test
void test11() throws IOException {
//需要被解压缩得文件路径和文件名
File file = new File("D:" + File.separator + "Hello.zip");
//解压缩之后得文件路径和文件名
File file1 = new File("D:" + File.separator + "java.txt");
ZipFile zipFile = new ZipFile(file);
//被压缩得单独文件得名称
ZipEntry entry = zipFile.getEntry("Hello.txt");
InputStream inputStream = zipFile.getInputStream(entry);
FileOutputStream fileOutputStream = new FileOutputStream(file1);
int temp;
while ((temp=inputStream.read())!=-1){
fileOutputStream.write(temp);
}
inputStream.close();
fileOutputStream.close();
}
需求12:压缩多个文件
/**
* 压缩多个文件
*/
@Test
void test12() throws IOException {
File files = new File("D:" + File.separator + "tables");
File zipFile = new File("D:" + File.separator + "ZipTables.zip");
InputStream input = null;
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFile));
//这里是设置压缩的备注
zipOutputStream.setComment("hello zip");
if (files.isDirectory()) {
//如果files是一个目录
File[] listFiles = files.listFiles();
for (int i = 0; i < listFiles.length; i++) {
input = new FileInputStream(listFiles[i]);
zipOutputStream.putNextEntry(new ZipEntry(files.getName() +
File.separator + listFiles[i].getName()));
int temp;
while ((temp = input.read()) != -1) {
zipOutputStream.write(temp);
}
input.close();
}
}
zipOutputStream.close();
}
}
需求13:解压缩多个文件
/**
* 解压缩多个文件
*/
@Test
void test13() throws Exception {
//需要被解压缩得文件
File files = new File("D:" + File.separator + "zipFiles.zip");
File outFile = null;
ZipFile zipFile = new ZipFile(files);
ZipInputStream zipInput = new ZipInputStream(new FileInputStream(files));
ZipEntry entry = null;
InputStream inputStream = null;
OutputStream output = null;
while ((entry = zipInput.getNextEntry()) != null) {
System.out.println("被解压缩得文件得文件名:" + entry.getName());
outFile = new File("D:" + File.separator + entry.getName());
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdir();
}
if (!outFile.exists()) {
outFile.createNewFile();
}
inputStream = zipFile.getInputStream(entry);
output = new FileOutputStream(outFile);
int temp;
while ((temp = inputStream.read()) != -1) {
output.write(temp);
}
inputStream.close();
output.close();
}
}
需求14:复制文件
/**
* 复制一个文件
*/
@Test
void test14() throws IOException {
File file = new File("D:" + File.separator + "java.txt");
File copyFile = new File("D:" + File.separator + "copy_Hello.txt");
FileInputStream inputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(copyFile);
int temp;
while ((temp=inputStream.read())!=-1){
fileOutputStream.write(temp);
}
inputStream.close();
fileOutputStream.close();
}
后面碰到其他新的常见需求后再对此文章进行补充。