[AppleScript] 纯文本查看 复制代码
public static void main(String[] args) {
// String getAbsolutePath(): 返回此File的绝对路径名字符串
File f1 = new File("a.txt");
System.out.println(f1.getAbsolutePath()); // File对象是相对路径, 该方法可以获取到绝对路径
// String getPath(): 获取File对象的封装路径 (创建对象时传入的路径)
System.out.println(new File("a.txt").getPath()); // 创建对象时是什么路径, 获取的就是什么
System.out.println(new File("d:\\a.txt").getPath());
// String getName(): 获取File对象的文件名或目录名
File f3 = new File("a\\b\\c\\d.txt");
System.out.println(f3.getName());
// long length(): 获取File表示的文件大小的字节数 (不能获取目录的大小)
File f4 = new File("day08\\src\\com\\itheima\\test02\\Test.java"); // 相对路径
System.out.println(f4.length()); // 1431
}
}
[AppleScript] 纯文本查看 复制代码
public class Test {
public static void main(String[] args) {
// boolean exists(): 判断File对象代表的文件或目录是否实际存在
File f1 = new File("day08\\src");
System.out.println(f1.exists());
// boolean isDirectory(): 判断File表示的是否为目录
File f2 = new File("day08\\src\\com\\itheima\\test03");
System.out.println(f2.isDirectory());
// boolean isFile(): 判断File表示的是否为文件
File f3 = new File("day08\\src\\com\\itheima\\test03\\Test.java");
System.out.println(f3.isFile());
}
}
// 常用创建删除方法
boolean?createNewFile(): 当文件不存在时, 创建一个新的空文件
boolean?delete(): 删除由此File表示的文件或目录. (删除目录时必须是空目录)
boolean?mkdir(): 创建File表示的目录
boolean?mkdirs(): 创建File表示的多级目录
代码实例;
public static void main(String[] args) throws IOException {
// 在当前的模块中创建a目录
/* File dirA = new File("day08\\a");
dirA.mkdir();
// 在a目录中创建b目录
File dirB = new File("day08\\a\\b");
dirB.mkdir();*/
// 以上两步可以合并为一步
File dirAB = new File("day08\\a\\b");
dirAB.mkdirs();
// 在b目录中创建b.txt文件和c.txt文件
File fileB = new File("day08\\a\\b\\b.txt");
fileB.createNewFile();
File fileC = new File("day08\\a\\b\\c.txt");
fileC.createNewFile();
// 删除c.txt文件
fileC.delete();
boolean result = new File("z:\\a").mkdirs(); // 磁盘不存在, 不会创建
System.out.println(result); // false
}
}
// 常用获取目录中内容的方法
String[]?list(): 获取当前File目录下的所有子文件或目录的名字数组
File[]?listFiles(): 获取当前File目录中的所有子文件或目录的File对象数组
File[] listFiles(FileFilter filter): 通过File对象过滤, 返回文件过滤器过滤后的File对象数组
File[] listFiles(FilenameFilter filter): 通过File对象的文件名过滤, 返回文件过滤器过滤后的File对象数组
java.io.FileFilter接口: 用于File对象的过滤器
boolean accept(File pathName): true则会将参数的File对象加入返回的File[], false则不加入
java.io.FilenameFilter接口:
boolean accept(File dir, String name): true则会将参数的File对象加入返回的File[], false则不加入
字节输入流【InputStream】
读取字节:read方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1,代码使用演示:
[AppleScript] 纯文本查看 复制代码
FileInputStream fis = new FileInputStream("read.txt");
// 定义变量,保存数据
int b ;
// 循环读取
while ((b = fis.read())!=-1) { b为读取到的数据
System.out.println((char)b); 强转为char
}
// 关闭资源
fis.close();
使用字节数组读取:read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1 ,代码使用演示:
FileInputStream fis = new FileInputStream("read.txt"); // 文件中为abcde
// 定义变量,作为有效个数
int len ;
// 定义字节数组,作为装字节数据的容器
byte[] b = new byte[2]; 数组的长度为2,每次读取两个字节
// 循环读取
[AppleScript] 纯文本查看 复制代码
while (( len= fis.read(b))!=-1) {
// 每次读取后,把数组变成字符串打印
System.out.println(new String(b));
}
// 关闭资源
fis.close();
输出结果:
ab
cd
ed
错误数据d,是由于最后一次读取时,只读取一个字节e,数组中,上次读取的数据没有被完全替换,所以要通过len ,获取有效的字节,代码使用演示:
[Java] 纯文本查看 复制代码
FileInputStream fis = new FileInputStream("read.txt"); // 文件中为abcde
// 定义变量,作为有效个数
int len ;
// 定义字节数组,作为装字节数据的容器
byte[] b = new byte[1024];或者是1024的倍数
// 循环读取
while (( len= fis.read(b))!=-1) {
// 每次读取后,把数组的有效字节部分,变成字符串打印
System.out.println(new String(b,0,len));// len 每次读取的有效字节个数
}
// 关闭资源
fis.close();
字节流读取中文问题
GBK编码中, 一个汉字占用2个byte
UTF-8编码中, 一个汉字占用3个byte
字符输入流:
[AppleScript] 纯文本查看 复制代码
FileReader fr = new FileReader("a.txt");
// 一次读一个字符
int ch; // 定义变量保存每次读到的字符
while ((ch = fr.read()) != -1) {
System.out.print((char)ch);
}
// 一次读一个字符数组
char[] cs = new char[1024];
int len;
while ((len = fr.read(cs)) != -1) {
String s = new String(cs, 0, len);
System.out.print(s);
}
// 释放资源
fr.close();
字符输出流: flush与close区别
区别:
flush(): 刷新缓冲区 (将数据从内存中写入到磁盘)
close(): 刷新缓冲区, 并释放资源. 关闭流后不能再用同一个流对象操作
Properties集合Properties存储数据和遍历:Properties双列集合,键和值都是 String 类型
java.util.Properties类: 属性集, 属于Map的双列集合, 继承自Hashtable
// 构造方法
Properties(): 创建一个Properties集合
// 可以使用Map接口中的方法
// 特有成员方法
Object setProperty(String key, String value): 保存/替换键值对
String getProperty(String key): 通过键获取值. 键不存在返回null
Set<String> stringPropertyNames(): 返回键的集合
void store(OutputStream out, String comments): 将集合用字节流写入文件(不能中文),并写入注释
void store(Writer writer, String comments): 将集合用字符流写入文件(可以中文),并写入注释
void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能读中文)
void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以读中文)
代码实例:
从Properties到硬盘:
[AppleScript] 纯文本查看 复制代码
public class Test {
public static void main(String[] args) throws IOException {
// 创建Properties集合对象
Properties properties = new Properties();
// 添加键值对 setProperty(String key, String value)
properties.setProperty("赵丽颖", "168");
properties.setProperty("迪丽热巴", "165");
properties.setProperty("古力娜扎", "160");
// 创建文件字符输出流对象
// FileWriter fw = new FileWriter("day09\\prop.properties");
FileWriter fw = new FileWriter("day09\\prop.txt");
// 将Properties集合中的数据, 写入到文件 store()
// properties.store(fw, "");
properties.store(fw, null); // 第二个参数注释, 传递null也可以, 这样就不会出现空行注释
// 关闭流
fw.close();
}
}
从硬盘到properties:
public class Test {
public static void main(String[] args) throws IOException {
// 创建Properties集合对象
Properties properties = new Properties();
// 创建文件字符输入流对象
FileReader fr = new FileReader("day09\\prop.properties");
// 从硬盘上读取到集合: load()
properties.load(fr); // 方法调用完毕后, 集合里面就有键值对了
// 遍历集合
Set<String> strings = properties.stringPropertyNames();
for (String key : strings) {
// 通过键获取值
String value = properties.getProperty(key);
System.out.println(key + "=" + value);
}
}
}
day10
file:///C:/Users/Administrator/AppData/Local/YNote/data/qq43AEA454F9E8FC8D3CE99A4053144AD8/5ab27db79d07448186f8b43fb33b9205/clipboard.png
缓冲流的原理:
底层也是使用基本流(FileXxx)来读写
但缓冲流内部定义了一个缓冲数组, 在读的时候类似于我们一次读一个数组的方式, 减少了磁盘操作次数, 提高了程序效率
字节缓冲输出流: BufferedOutputStream
构造方法
BufferedOutputStream(OutputStream out): 使用基本流创建一个缓冲字节输出流BufferedOutputStream(OutputStream out, int size): size是设置缓冲区大小
1.创建Fileoutputstream,构造方法中绑定要输出的目的地
2.创建Bufferedoutputstream,构造方法中传递Fileoutputsream对象,提高Fileoutputsream效率.
3.使用Bufferedoutputstream对象的方法write,把数据写入到内存缓冲区中
4.使用Bufferedoutputstream对象的方法flush,把内存缓冲区的数据刷新到文件中
5.释放资源.close(会调用flush方法刷新数据,第四部可以省略)
代码实例:
[AppleScript] 纯文本查看 复制代码
public static void main(String[] args) throws IOException {
BufferedOutputStream bo =
new BufferedOutputStream(newFileOutputStream("D:\\test.txt"));
bo.write("我就是爱音乐,别让我停下来".getBytes());
bo.close();}
字节缓冲输入流: BufferedInputStream
构造方法
BufferedInputStream(InputStream in): 使用基本流创建一个缓冲字节输入流
BufferedInputStream(InputStream in, int size): size为设置缓冲区大小
使用步骤:
1.创建FileInputStream对象, 构造方法中绑定要读取的数据源
2.创建BufferedInputStream对象, 构造方法中传递FileInputStream对象, 提高FileInputStream效率
3.使用BufferedInputStream对象中的方法 read(), 读取文件
4.释放资源 close()
代码实例:
[AppleScript] 纯文本查看 复制代码
public static void main(String[] args) throws IOException {
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("D:\\test.txt"));
int len;
while((len=bis.read())!=-1){
System.out.println(len);
}
bis.close();
// 或者:
// byte[]bytes=new byte[1024];
// int len;
// while((len=bis.read(bytes))!=-1){
// System.out.print(new String(bytes,0,len)); 将数组转换成字符串,从0开始转换,len:有效个数
// }
// bis.close();
}
缓冲字符输出流: BufferedWriter(与字节缓冲输出流类似)
代码实例:
[AppleScript] 纯文本查看 复制代码
BufferedWriter bw=new BufferedWriter(new FileWriter("day10\\testBufferedWriter1.txt",true));
for (int i = 0; i < 10; i++) {
bw.write("传智播客");
bw.newLine();换行也可以使用"\r\n"
}
bw.flush();
bw.close();
}
缓冲字符输入流: BufferedReader
代码实例:
[AppleScript] 纯文本查看 复制代码
BufferedReader br=new BufferedReader(new FileReader("day10\\testBufferedWriter1.txt"));
// String line;
// while((line=br.readLine())!=null){ readline一次读一行返回的是一行的数据
// System.out.println(line);
// }
// br.close();
// 或者:
int line;
char[] chars=new char[1024];
while((line=br.read(chars))!=-1){
System.out.println(new String(chars,0,line));
}
br.close();
}
转换流字符编码和字符集
编码: 字符 -> 字节 'a' -> 97
解码: 字节 -> 字符 97 -> 'a'
编码表: 字符和二进制数字的对应规则
字符集和编码表: 字符集包含编码表
ASCII字符集
ASCII编码表
ISO-8859-1字符集:
Latin-1: 拉丁字符. 没有中文. 每个字符由1个byte组成
GB字符集
GB2312编码表: 每个字符由2个byte组成
GBK编码表: 每个字符由2个byte组成
GB18030编码表: 每个字符由1, 2, 4个byte组成
Unicode
UTF-8: ASCII字符占1个byte, 拉丁字符占2个byte, 中文占3个byte, Unicode辅助字符占4个byte
UTF-16
UTF-32
代码实例:
[AppleScript] 纯文本查看 复制代码
public static void main(String[] args) throws IOException {
// 创建输入转换流
InputStreamReader isr = new InputStreamReader(new FileInputStream("day10\\我是GBK文件.txt"), "GBK");
// 创建输出转换流
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day10\\我是UTF_8文件.txt"), "UTF-8");
// 循环读写: 一次读写一个字符char
int ch;
while ((ch = isr.read()) != -1) {
// 读到的字符, 经过InputStreamReader已经按照GBK转换为正确的"你好"
// 接下来交给OutputStreamWriter写出去, 写的时候会按照UTF-8转换为UTF-8的byte
osw.write(ch);
}
// 刷新并释放资源
isr.close();
osw.close();
}
序列化流(对象流)序列化和反序列化
序列化: 内存中的对象转换为字节序列, 以流的方式写入到磁盘的文件中对象转字节
反序列化: 磁盘文件中的字节序列, 以流的方式读取到内存中变成对象字节转对象
通过序列化流, 我们可以将内存中的数据方便的存储到磁盘上, 下次程序启动后也能从磁盘读取恢复之前的对象状态
public class Person implements Serializable(被读写的对象的类, 必须实现 java.io.Serializable 接口, 否则会抛出 NotSerializableException)
[Java] 纯文本查看 复制代码
ArrayList<Person>list =new ArrayList<>();
list.add(new Person("张三",18));
list.add(new Person("李四",19));
list.add(new Person("张王五",20));
ObjectOutputStream op=new ObjectOutputStream(new FileOutputStream("day10\\list.txt"));
ObjectInputStream oi=new ObjectInputStream(new FileInputStream("day10\\list.txt"));
op.writeObject(list);
Object o = oi.readObject();
ArrayList<Person> list1 = (ArrayList<Person>) o;
for (Person person : list1) {
System.out.println(person);
InvalidClassException异常: 原因和解决方案
serialVersionUID序列号的作用:
序列化操作时, 会根据类生成一个默认的 serialVersionUID 属性, 写入到文件中.
该版本号是根据类中成员计算出来的一个数值. 当类的成员发生改变时, 序列版本号也会发生变化
当代码中的类和读取的对象序列版本号不一致时, 就会抛出InvalidClassException
为了避免这种问题, 我们可以手动写死这个序列号, 这样无论成员如何变化, 序列版本号都是一样的
补充: IDEA设置生成序列版本号:
Setting -> Editor -> Inspections -> Java -> Serialization issues -> 勾选Serializable class without 'serialVersionUID'
打印流
可以改变输出语句的目的地(打印流的流向)
输出语句默认在控制台上输出
使用system.setout改变输出语句的目的地改为参数中传递打印流的目的地
代码实例:
[Java] 纯文本查看 复制代码
System.out.println("我是在控制台上输出");
PrintStream p=new PrintStream("目的地.txt");
System.out.println("我在打印流的目的地中输出");
p.close();