IO系列学习
JAVA 的FILE类,以及常用方法
使用绝对路径或者相对路径创建File对象
package com.example.IO;
import java.io.File;
public class Test1 {
public static void main(String[] args) {
//绝对路径
File f1 = new File("G:\\File");
System.out.println("f1的相对路径"+f1.getAbsolutePath());
// 相对路径,相对于工作目录,如果在idea中,就是项目目录 和你的claas 在一起
File f2 = new File("file.txt");
System.out.println("f2的相对路径"+f2.getAbsolutePath());
File f3 =new File(f1,"file.txt");
// 把f1作为父目录创建文件对象
System.out.println("f3的相对路径"+f3.getAbsolutePath());
}
}
运行结果
f1的相对路径G:\File
f2的相对路径F:\IDEA_gulimall\Login_Register\yanwc\file.txt
f3的相对路径G:\File\file.txt
注意1: 需要在D:\LOLFolder确实存在一个LOL.exe,才可以看到对应的文件长度、修改时间等信息
注意2: renameTo方法用于对物理文件名称进行修改,但是并不会修改File对象的name属性
package com.example.IO;
import java.io.File;
import java.util.Date;
public class Test1 {
public static void main(String[] args) {
File f = new File("G:\\File\\file.txt");
System.out.println("当前文件是:" + f);
//文件是否存在
System.out.println("判断是否存在:" + f.exists());
//是否是文件夹
System.out.println("判断是否是文件夹:" + f.isDirectory());
//是否是文件(非文件夹)
System.out.println("判断是否是文件:" + f.isFile());
//文件长度
System.out.println("获取文件的长度:" + f.length());
//文件最后修改时间
long time = f.lastModified();
Date d = new Date(time);
System.out.println("获取文件的最后修改时间:" + d);
//设置文件修改时间为1970.1.1 08:00:00
f.setLastModified(0);
//文件重命名
File f2 = new File("G:\\File\\FILE.txt");
f.renameTo(f2);
System.out.println("把file改名成了FILE");
System.out.println("修改名字后的结果是"+f2);
System.out.println("注意: 需要在G:\\File存在FILE,\r\n才可以看到对应的文件长度、修改时间等信息");
}
}
运行结果是
当前文件是:G:\File\file.txt
判断是否存在:true
判断是否是文件夹:false
判断是否是文件:true
获取文件的长度:0
获取文件的最后修改时间:Thu Jan 01 08:00:00 CST 1970
把file改名成了FILE
修改名字后的结果是G:\File\FILE.txt
注意: 需要在G:\File存在FILE,
才可以看到对应的文件长度、修改时间等信息
文件常用设置
package file;
import java.io.File;
import java.io.IOException;
public class TestFile {
public static void main(String[] args) throws IOException {
File f = new File("d:/LOLFolder/skin/garen.ski");
// 以字符串数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
f.list();
// 以文件数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
File[]fs= f.listFiles();
// 以字符串形式返回获取所在文件夹
f.getParent();
// 以文件形式返回获取所在文件夹
f.getParentFile();
// 创建文件夹,如果父文件夹skin不存在,创建就无效
f.mkdir();
// 创建文件夹,如果父文件夹skin不存在,就会创建父文件夹
f.mkdirs();
// 创建一个空文件,如果父文件夹skin不存在,就会抛出异常
f.createNewFile();
// 所以创建一个空文件之前,通常都会创建父目录
f.getParentFile().mkdirs();
// 列出所有的盘符c: d: e: 等等
f.listRoots();
// 刪除文件
f.delete();
// JVM结束的时候,刪除文件,常用于临时文件的删除
f.deleteOnExit();
}
}
练习1
一般说来操作系统都会安装在C盘,所以会有一个 C:\WINDOWS目录。
遍历这个目录下所有的文件(不用遍历子目录)
找出这些文件里,最大的和最小(非0)的那个文件,打印出他们的文件名
注: 最小的文件不能是0长度
package com.example.IO;
import java.io.File;
import java.util.Arrays;
import java.util.Date;
public class Test1 {
public static void main(String[] args) {
long minSize = Integer.MAX_VALUE; 定义一个最大值,方便后面最小值的赋值
long maxSize = 0;//定义为0,方便后面最大值的赋值
//定义最大字节和最小文件
File Maxfile = null;
File Minfile = null;
File f1 = new File("D:\\XMind");
Boolean f2 = f1.exists();
System.out.println("查看是否存在改文件夹" + f2);
//为空直接返回
if (f2 == false) {
return;
}
File[] fs = f1.listFiles();
//数组转换
System.out.println("fs" + Arrays.toString(fs));
for (File file : fs) {
if (file.isDirectory()) {
continue;//如果是文件夹,则跳出此次循环
}
//如果文件字节大小大于0
if (file.length() > maxSize) {
maxSize = file.length();//将字节大小赋值给maxSize
Maxfile = file;//将文件名赋值给maxFile
}
//判断文件字节大小不为o,且小于minSize,
//第二次循环进来的时候,如果第二次文件字节大小小于第一次,则再一次进行赋值,循环结束,则有最小字节数
if (file.length()!=0 && file.length()<minSize){
minSize = file.length();;
Minfile = file;
}
}
System.out.println("最大的文件是"+Maxfile+",其大小是"+maxSize+"字节");
System.out.println("最小的文件是"+Minfile+",其大小是"+minSize+"字节");
}
}
结果为:
查看是否存在改文件夹true
fs[D:\XMind\artifacts.xml, D:\XMind\bcl-java.txt, D:\XMind\configuration, D:\XMind\epl-v10.html, D:\XMind\features, D:\XMind\jre, D:\XMind\lgpl-3.0.html, D:\XMind\p2, D:\XMind\plugins, D:\XMind\readme.txt, D:\XMind\thirdparty, D:\XMind\tools, D:\XMind\unins000.dat, D:\XMind\unins000.exe, D:\XMind\XMind-original.ini, D:\XMind\XMind.exe, D:\XMind\XMind.ini, D:\XMind\xmindshell.dll, D:\XMind\xmind_file.ico, D:\XMind\xmind_xmp.ico, D:\XMind\xmind_xmt.ico]
最大的文件是D:\XMind\unins000.exe,其大小是1196233字节
最小的文件是D:\XMind\XMind-original.ini,其大小是506字节
什么JAVA 的流 STREAM?
什么是流(Stream),流就是一系列的数据
比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流
输入流: InputStream
输出流:OutputStream
如下代码,就建立了一个文件输入流,这个流可以用来把数据从硬盘的文件,读取到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();
}
}
}
输出流
package file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class TestStream {
public static void main(String[] args) {
File f =new File("d:/lol.txt");
try {
FileOutputStream fos = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
JAVA 字节流 INPUTSTREAM OUTPUTSTREAM
InputStream字节输入流
OutputStream字节输出流
用于以字节的形式读取和写入数据
步骤 1 : ASCII码 概念
所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放。
比如A就对应的数字65,a对应的数字97. 不同的字母和符号对应不同的数字,就是一张码表。
ASCII是这样的一种码表。 只包含简单的英文字母,符号,数字等等。 不包含中文,德文,俄语等复杂的。
示例中列出了可见的ASCII码以及对应的十进制和十六进制数字,不可见的暂未列出
| 字符 | 十进制数字 | 十六进制数字 |
|---|---|---|
| ! | 33 | 21 |
| " | 34 | 22 |
| # | 35 | 23 |
| $ | 36 | 24 |
| % | 37 | 25 |
| & | 38 | 26 |
| ’ | 39 | 27 |
| ( | 40 | 28 |
| ) | 41 | 29 |
| * | 42 | 2A |
| + | 43 | 2B |
| , | 44 | 2C |
| - | 45 | 2D |
| . | 46 | 2E |
| / | 47 | 2F |
| 0 | 48 | 30 |
| 1 | 49 | 31 |
| 2 | 50 | 32 |
| 3 | 51 | 33 |
| 4 | 52 | 34 |
| 5 | 53 | 35 |
| 6 | 54 | 36 |
| 7 | 55 | 37 |
| 8 | 56 | 38 |
| 9 | 57 | 39 |
| : | 58 | 3A |
| ; | 59 | 3B |
| < | 60 | 3C |
| = | 61 | 3D |
| 大于号 | 62 | 3E |
| @ | 64 | 40 |
| A | 65 | 41 |
| B | 66 | 42 |
| C | 67 | 43 |
| D | 68 | 44 |
| E | 69 | 45 |
| F | 70 | 46 |
| G | 71 | 47 |
| H | 72 | 48 |
| I | 73 | 49 |
| J | 74 | 4A |
| K | 75 | 4B |
| L | 76 | 4C |
| M | 77 | 4D |
| N | 78 | 4E |
| O | 79 | 4F |
| P | 80 | 50 |
| Q | 81 | 51 |
| R | 82 | 52 |
| S | 83 | 53 |
| T | 84 | 54 |
| U | 85 | 55 |
| V | 86 | 56 |
| W | 87 | 57 |
| X | 88 | 58 |
| Y | 89 | 59 |
| Z | 90 | 5A |
| [ | 91 | 5B |
| \ | 92 | 5C |
| ] | 93 | 5D |
| 94 | 5E | |
| _ | 95 | 5F |
| ` | 96 | 60 |
| a | 97 | 61 |
| b | 98 | 62 |
| c | 99 | 63 |
| d | 100 | 64 |
| e | 101 | 65 |
| f | 102 | 66 |
| g | 103 | 67 |
| h | 104 | 68 |
| i | 105 | 69 |
| j | 106 | 6A |
| k | 107 | 6B |
| l | 108 | 6C |
| m | 109 | 6D |
| n | 110 | 6E |
| o | 111 | 6F |
| p | 112 | 70 |
| q | 113 | 71 |
| r | 114 | 72 |
| s | 115 | 73 |
| t | 116 | 74 |
| u | 117 | 75 |
| v | 118 | 76 |
| w | 119 | 77 |
| x | 120 | 78 |
| y | 121 | 79 |
| z | 122 | 7A |
| { | 123 | 7B |
| 竖杠 | 124 | 7C |
| } | 125 | 7D |
| ~ | 126 | 7E |
步骤 2 : 以字节流的形式读取文件内容
InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。 FileInputStream
是InputStream子类,以FileInputStream 为例进行文件读取
InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取
package com.example.IO;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
public class Test1 {
public static void main(String[] args) {
try {
//准备文件file.txt其中的内容是AB,对应的ASCII分别是65 66
File file = new File("G:\\File\\file.txt");
//创建基于文件的输入流
FileInputStream fis = new FileInputStream(file);
//创建字节数组,其长度就是文件的长度(强转)
byte[] all = new byte[(int) file.length()];
//以字节流的形式读取文件所有内容
fis.read(all);
for (byte b : all) {
//打印出来是65 66
System.out.println(b);
}
//每次使用完关闭流不然占用内存会比较大
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果
65
66
步骤 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();
}
}
}
关闭流的方式
在try中关闭
在try的作用域里关闭文件输入流,在前面的示例中都是使用这种方式,这样做有一个弊端;
如果文件不存在,或者读取的时候出现问题而抛出异常,那么就不会执行这一行关闭流的代码,存在巨大的资源占用隐患。 不推荐使用
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);
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
// 在try 里关闭流
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在finally中关闭
这是标准的关闭流的方式
- 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.
- 在finally关闭之前,要先判断该引用是否为空
- 关闭的时候,需要再一次进行try catch处理
这是标准的严谨的关闭流的方式,但是看上去很繁琐,所以写不重要的或者测试代码的时候,都会采用上面的有隐患try的方式,因为不麻烦~
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
File f = new File("d:/lol.txt");
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 在finally 里关闭流
if (null != fis)
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
使用try()的方式
把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术
所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源。
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
File f = new File("d:/lol.txt");
//把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
try (FileInputStream fis = new FileInputStream(f)) {
byte[] all = new byte[(int) f.length()];
fis.read(all);
for (byte b : all) {
System.out.println(b);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
**在finally中关闭**
这是标准的关闭流的方式
- 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.
- 在finally关闭之前,要先判断该引用是否为空
- 关闭的时候,需要再一次进行try catch处理
这是标准的严谨的关闭流的方式,但是看上去很繁琐,所以写不重要的或者测试代码的时候,都会采用上面的有隐患try的方式,因为不麻烦~
package com.example.IO;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class TestStream {
public static void main(String[] args) {
//文件中字母 随意 字节码转化
File file = new File("F:\\IDEA_gulimall\\Login_Register\\yanwc\\src\\main\\java\\com\\example\\IO\\file.txt");
FileInputStream fis = null;
try{
fis=new FileInputStream(file);
byte[] all=new byte[(int) file.length()];
fis.read(all);
for(byte n:all){
System.out.println(n);
}
}catch (Exception e){
e.printStackTrace();
}finally { // 在finally 里关闭流
if (null!=fis) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
57
54
使用try()的方式
把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术
所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源
package com.example.IO;
import java.io.File;
import java.io.FileInputStream;
public class TestStream {
/*public static void main(String[] args) {
//文件中字母 随意 字节码转化
File file = new File("F:\\IDEA_gulimall\\Login_Register\\yanwc\\src\\main\\java\\com\\example\\IO\\file.txt");
FileInputStream fis = null;
try{
fis=new FileInputStream(file);
byte[] all=new byte[(int) file.length()];
fis.read(all);
for(byte n:all){
System.out.println(n);
}
}catch (Exception e){
e.printStackTrace();
}finally { // 在finally 里关闭流
if (null!=fis) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
*/
public static void main(String[] args) {
//文件中字母 随意 字节码转化
File file = new File("F:\\IDEA_gulimall\\Login_Register\\yanwc\\src\\main\\java\\com\\example\\IO\\file.txt");
try{
//把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
FileInputStream fis = null;
fis=new FileInputStream(file);
byte[] all=new byte[(int) file.length()];
fis.read(all);
for(byte n:all){
System.out.println(n);
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
结果
57
54
IO字符流
Reader字符输入流
Writer字符输出流
专门用于字符的形式读取和写入数据
使用字符流读取文件
FileReader 是Reader子类,以FileReader 为例进行文件读取
package com.example.IO;
import java.io.File;
import java.io.FileReader;
public class TestStream1 {
public static void main(String[] args) {
// 准备文件lol.txt其中的内容是56
File file = new File("F:\\IDEA_gulimall\\Login_Register\\yanwc\\src\\main\\java\\com\\example\\IO\\file.txt");
// 创建基于文件的Reader
try(FileReader reader=new FileReader(file)) {
// 创建字符数组,其长度就是文件的长度
char[] le=new char[(int) file.length()];
reader.read(le);
for (char ne:le){
// 打印出来是56
System.out.println(ne);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
运行结果是
9
6
使用字符流把字符串写入到文件
FileWriter 是Writer的子类,以FileWriter 为例把字符串写入到文件
public static void main(String[] args) {
File file = new File("F:\\IDEA_gulimall\\Login_Register\\yanwc\\src\\main\\java\\com\\example\\IO\\file.txt");
try(FileWriter writer=new FileWriter(file)){
String ate="asdcderwerwew";
char[] ss=ate.toCharArray();
writer.write(ss);
System.out.println("执行完成");
}catch (Exception e){
e.printStackTrace();
}
}
运行结果是
执行完成
更新中,未完成;