文章目录
输入输出流,常见文件操作
01 文件对象
文件和文件夹都是用File代表。
1.1 创建一个文件对象
使用绝对路径或者相对路径创建File对象。实际上,没有创建文件。
基本语法:File f=new File("路径");
// 绝对路径
File f1 = new File("d:/LOLFolder");
System.out.println("f1的绝对路径:" + f1.getAbsolutePath());
// 相对路径,相对于工作目录,如果在eclipse中,就是项目目录
File f2 = new File("LOL.exe");
System.out.println("f2的绝对路径:" + f2.getAbsolutePath());
// 把f1作为父目录创建文件对象
File f3 = new File(f1, "LOL.exe");
System.out.println("f3的绝对路径:" + f3.getAbsolutePath());
1.2 文件的常用方法1
-
创建文件对象
File f=new File("d:/LOLFolder/LOL.exe");
-
判断文件是否存在,返回boolean值
f.exists();
-
判断文件是否是文件夹,返回boolean值
f.isDirectory();
-
判断文件是否是文件(非文件夹),返回boolean值
f.isFile();
-
获取文件的长度
f.length();
-
获取文件最后修改时间
long time = f.lastModified(); Date d = new Date(time);
-
设置文件最后修改时间
f.setLastModified(0); //设为1970.1.1 08:00:00
-
文件重命名(renameTo方法用于对物理文件名称进行修改,但是并不会修改File对象的name属性。)
File f2 =new File("d:/LOLFolder/DOTA.exe");
f.renameTo(f2);
//由LOL.exe改为DOTA.exe
1.3 文件的常用方法2
- 创建文件对象
File f=new File("d:/LOLFolder/skin/garen.ski");
- 获取当前文件夹下的文件
f.list(); //以字符串数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹) File[] fs=f.listFiles; //以文件数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
- 获取所在文件夹
f.getParent();
//以字符串形式返回获取所在文件夹
f.getParentFile();
//以文件形式获取所在文件夹
- 创建文件夹
f.mkdir();
//创建文件夹,如果父文件夹skin不存在,就创建无效
f.mkdirs();
//创建文件夹,如果父文件夹skin不存在,就会创建父文件夹
f.creatNewFile();
//创建一个空文件夹,如果父文件夹skin不存在,就会抛出异常
//所以创建一个空文件夹之前,通常都会创建父文件夹
f.getParentFile.mkdirs();
- 列出所有盘符
f.listRoots();
//列出所有的盘符c: d: e: 等等
- 删除文件
f.delete();
//删除文件
f.deleteOnExit();
//JVM结束时,删除文件,常用于临时文件的删除
1.4 练习
- 遍历一个文件夹,并找出最大的和最小(非0)的那个文件;
- 遍历一个文件夹下所有文件,并找出最大的和最小(非0)的那个文件;
02 什么是流
什么是流(Stream),流就是一系列的数据。
2.1 流的理解
当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件,还可以是数据库,网络甚至是其他的程序。
比如:读取文件的数据到程序中,站在程序的角度来看,就叫做输入流
输入流: InputStream;
输出流:OutputStream。
2.2 文件输入流
如下代码,就建立了一个文件输入流,这个流可以用来把数据从硬盘的文件,读取到JVM(内存)。
目前代码只是建立了流,还没有开始读取。
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
try {
File f = new File("d:/lol.txt");
// 创建基于文件的输入流
FileInputStream fis = new FileInputStream(f);
// 通过这个输入流,就可以把数据从硬盘,读取到Java的虚拟机中来,也就是读取到内存中
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.3 文件输出流
try {
File f=new File("d:/lol.txt");
FileOutputStream fos=new FileOutputStream(f);
}catch(IOException ioe) {
ioe.getStackTrace();
}
03 字节流
InputStream字节输入流;
OutputStream字节输出流;
用于以字节的形式读取和写入数据。
3.1 ASCII码
所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放。
3.2 以字节流的形式读取文件内容
InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取.
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
try {
//准备文件lol.txt其中的内容是AB,对应的ASCII分别是65 66
File f =new File("d:/lol.txt");
//创建基于文件的输入流
FileInputStream fis =new FileInputStream(f);
//创建字节数组,其长度就是文件的长度
byte[] all =new byte[(int) f.length()];
//以字节流的形式读取文件所有内容
fis.read(all);
for (byte b : all) {
//打印出来是65 66
System.out.println(b);
}
//每次使用完流,都应该进行关闭
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.3 以字节流的形式向文件写入数据
OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据。
注: 如果文件d:/lol2.txt不存在,写出操作会自动创建该文件。
但是如果是文件 d:/xyz/lol2.txt,而目录xyz又不存在,会抛出异常
package stream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
try {
// 准备文件lol2.txt其中的内容是空的
File f = new File("d:/lol2.txt");
// 准备长度是2的字节数组,用88,89初始化,其对应的字符分别是X,Y
byte data[] = {
88, 89 };
// 创建基于文件的输出流
FileOutputStream fos = new FileOutputStream(f);
// 把数据写入到输出流
fos.write(data);
// 关闭输出流
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
练习之文件和目录不存在时,如何写入文件
package stream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
try {
File f = new File("d:/xyz/abc/def/lol2.txt");
//因为默认情况下,文件系统中不存在 d:\xyz\abc\def,所以输出会失败
//首先获取文件所在的目录
File dir = f.getParentFile();
//如果该目录不存在,则创建该目录
if(!dir.exists()){
// dir.mkdir(); //使用mkdir会抛出异常,因为该目录的父目录也不存在
dir.mkdirs(); //使用mkdirs则会把不存在的目录都创建好
}
byte data[] = {
88, 89 };
FileOutputStream fos = new FileOutputStream(f);
fos.write(data);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
练习之拆分文件
package file;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
/*
*@Author hmg
*@Description
*@Time 2019年11月24日下午3:53:52
*@Version1.0
*/
public class TestFile {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
File inf =new File("e:/eclipse.exe");
FileInputStream fis=new FileInputStream(inf);
byte[] all=new byte[(int)inf.length()];
fis.read(all);
int part=all.length/(100*1024);
File[] ouf=new File[part+1];
for(int i=0;i<ouf.length;i++) {
String str="e:/eclipse.exe"+"-"+i;
ouf[i]=new File(str);
}
for(int i=0;i<=part;i++) {
FileOutputStream fos=new FileOutputStream(ouf[i]);
if(i==part) {
int rest=all.length%(100*1024);
fos.write(all, i*100*1024,rest );
System.out.printf("输出子文件%s,大小是%d字节%n",ouf[i].getAbsoluteFile(),rest);
fos.close();
}
else {
fos.write(all, i*100*1024, 100*1024);
System.out.printf("输出子文件%s,大小是%d字节%n",ouf[i].getAbsoluteFile(),100*1024);
fos.close();
}
}
fis.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
答案:
package file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class TestFile {
public static void main(String[] args) {
int eachSize = 100 * 1024; // 100k
File srcFile = new File("e:/eclipse.exe");
splitFile(srcFile, eachSize);
}
/**
* 拆分的思路,先把源文件的所有内容读取到内存中,然后从内存中挨个分到子文件里
* @param srcFile 要拆分的源文件
* @param eachSize 按照这个大小,拆分
*/
private static void splitFile(File srcFile, int eachSize) {
if (0 == srcFile.length())
throw new RuntimeException("文件长度为0,不可拆分");
byte[] fileContent = new byte[(int) srcFile.length()];
// 先把文件读取到数组中
try {
FileInputStream fis = new FileInputStream(srcFile);
fis.read(fileContent);
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 计算需要被划分成多少份子文件
int fileNumber;
// 文件是否能被整除得到的子文件个数是不一样的
// (假设文件长度是25,每份的大小是5,那么就应该是5个)
// (假设文件长度是26,每份的大小是5,那么就应该是6个)
if (0 == fileContent.length % eachSize)
fileNumber = (int) (fileContent.length / eachSize);
else
fileNumber = (int) (fileContent.length / eachSize) + 1;
for (int i = 0; i < fileNumber; i++) {
String eachFileName = srcFile.getName() + "-" + i;
File eachFile = new File(srcFile.getParent(), eachFileName);
byte[] eachContent;
// 从源文件的内容里,复制部分数据到子文件
// 除开最后一个文件,其他文件大小都是100k
// 最后一个文件的大小是剩余的