文件编码
idea查看项目的编码:File -> Setting -> Editor -> File Encodings,其中有Global Encoding(全局编码),Project Encoding(项目编码)。
public class EncodeDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "学习io流";
byte[] b1 = str.getBytes();// 转换成字节序列用的是项目默认的编码
System.out.println("b1的编码为:(编码集为项目设置编码)");
for (byte b : b1) {
// toHexString()函数:把字节自动转换成了int类型,以16进制的方式显示
System.out.print(Integer.toHexString(b & 0xff)+" ");
}
System.out.println("\n b2的编码为:(编码集为GBK)");
byte[] b2 = str.getBytes("GBK");
for (byte b : b2) {
System.out.print(Integer.toHexString(b & 0xff) + " ");
}
System.out.println("\n b3的编码为:(编码集为utf-8)");
byte[] b3 = str.getBytes(StandardCharsets.UTF_8);
for (byte b : b3) {
System.out.print(Integer.toHexString(b & 0xff) + " ");
}
System.out.println("\n b4的编码为:(编码集为utf-16be)");
byte[] b4 = str.getBytes(StandardCharsets.UTF_16BE);
for (byte b : b4) {
System.out.print(Integer.toHexString(b & 0xff) + " ");
}
System.out.println();
/**
* 由此可见:
* GBK编码中文占2个字节,英文占1个字节
* utf-8编码中文占3个字节,英文占1个字节
* utf-16be中文占2个字节,英文占2个字节
*
* Java是双字节编码(utf-16be编码)
*
* 当你的字节序列是某种编码时,想把字节序列变成字符串,也需要这种编码方式,
* 否则会出现乱码
*/
String str1 = new String(b4);
System.out.println(str1);
String str2 = new String(b4, StandardCharsets.UTF_16BE);
System.out.println(str2);
/**
* 文本文件就是字节序列,可以是任意编码的字节序列
* 如果我们在中文机器(Windows)上直接创建文本文件,那么该文本文件只认识ANSI编码
*/
}
}输出结果:
b1的编码为:(编码集为项目设置编码) e5 ad a6 e4 b9 a0 69 6f e6 b5 81 b2的编码为:(编码集为GBK) d1 a7 cf b0 69 6f c1 f7 b3的编码为:(编码集为utf-8) e5 ad a6 e4 b9 a0 69 6f e6 b5 81 b4的编码为:(编码集为utf-16be) 5b 66 4e 60 0 69 0 6f 6d 41 [fN` i omA 学习io流
File类常用API介绍
java.io.File类用于表示文件(目录)。
File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问。
public class FileDemo {
public static void main(String[] args) {
// 了解构造函数的情况,可以在File上使用快捷键:Alt+/
File f1 = new File("F:\\000学习资料\\01JavaWeb笔记");
System.out.println(f1);
System.out.println("判断该文件夹(目录)是否存在:"+f1.exists());
File f2 = new File("F:\\000学习资料\\01JavaWeb笔记\\io输入输出");
if (!f2.exists()) {
f2.mkdir(); //表示如果文件夹(目录)不存在则创建单级目录
// f2.mkdirs();//可以创建多级目录
} else {
f2.delete(); //如果存在则删除
}
// File.separator 在此路径结束后追加分隔符( \ )
File f3 = new File("F:\\000学习资料\\01JavaWeb笔记", File.separator);
System.out.println(f3);
// 判断是否是一个目录,如果是则返回true,如果不是目录或者不存在则返回false
System.out.println(f3.isDirectory());
// 判断是否是一个文件,(同上)
System.out.println(f3.isFile());
// File f4 = new File("F:\\000学习资料\\01JavaWeb笔记\\io.txt");
// 与上面的方法实现功能相同,只是该方法的逗号前面指定父级,后面指定子级
File f4 = new File("F:\\000学习资料\\01JavaWeb笔记","io.txt");
if (!f4.exists()) { //判断该文件是否存在
try {
f4.createNewFile(); //如果不存在则创建该文本文件
} catch (IOException e) {
e.printStackTrace();
}
} else {
f4.delete(); //如果存在则删除
}
// 常用的file对象API
System.out.println("f1的内容:"+f1.toString());
System.out.println("f1的绝对路径:"+f1.getAbsoluteFile());
System.out.println("f1的名字:"+f1.getName());
System.out.println("f2的名字:"+f2.getName());
System.out.println("获取f2的父级:"+f2.getParent());
System.out.println("获取f2的父级文件:"+f2.getParentFile());
}
}输出结果:
F:\000学习资料\01JavaWeb笔记 判断该文件夹(目录)是否存在:true F:\000学习资料\01JavaWeb笔记\ true false f1的内容:F:\000学习资料\01JavaWeb笔记 f1的绝对路径:F:\000学习资料\01JavaWeb笔记 f1的名字:01JavaWeb笔记 f2的名字:io输入输出 获取f2的父级:F:\000学习资料\01JavaWeb笔记 获取f2的父级文件:F:\000学习资料\01JavaWeb笔记
遍历目录
写一个FileUtils工具类,列出File的一些常用操作,比如过滤、遍历等操作,以方便项目以后的使用:
public class FileUtils {
/**
* 列出指定目录下(包括其子目录)的所有文件
* @param dir
* @throws IOException
*/
public static void listDirectory(File dir) throws IOException {
if (!dir.exists()) {
throw new IllegalArgumentException("目录"+dir+"不存在~");
}
if (!dir.isDirectory()) {
throw new IllegalArgumentException(dir+"不是目录~");
}
// dir.list():返回字符串数组,直接子目录的名称,不包括子目录下的文件
// String[] fileNames = dir.list();
// for (String fileName : fileNames) {
// System.out.println(dir+"\\"+fileName);
// }
// 如果要遍历子目录下的文件,就需要构造File对象做递归操作,File提供了直接返回file对象的API
File[] files = dir.listFiles();
// for (File file : files) {
// System.out.println(file);// 返回的是直接子目录(文件)的抽象
// }
if (files != null && files.length > 0) {
for (File file : files) {
if (file.isDirectory()) {
// 递归
listDirectory(file);
}
System.out.println(file);
}
}
}
}遍历目录测试类:
public class ErgodicTest {
public static void main(String[] args) throws IOException {
FileUtils.listDirectory(new File("F:\\000学习资料\\01JavaWeb笔记\\04输入输出流"));
}
}输出结果:
F:\000学习资料\01JavaWeb笔记\04输入输出流\0704.md F:\000学习资料\01JavaWeb笔记\04输入输出流\io\io.txt F:\000学习资料\01JavaWeb笔记\04输入输出流\io
RandomAccessFile类
RandomAccessFile是Java提供的对文件内容的访问,既可以读文件,也可以写文件。支持随机访问文件,可以访问文件的任意位置。
(1)Java文件模型:
在硬盘上的文件是用字节存储的,是数据的集合。
(2)打开文件(四种模式):
| 模式 | 说明 |
|---|---|
| r | 以只读的方式打开文本,也就意味着不能用write来操作文件 |
| rw | 读操作和写操作都是允许的 |
| rws | 每当进行写操作,同步的刷新到磁盘,刷新内容和元数据 |
| rwd | 每当进行写操作,同步的刷新到磁盘,刷新内容 |
RandomAccessFile raf = new RandomAccessFile(file, "rw");
文件指针:打开文件时指针为0(pointer = 0;).
(3)写方法
raf.write(type) --> 每次只写一个字节(后8位,如果要写一个int类型数据,则需要写4次),同时指针指向下一个位置,准备下一次写入
(4)读方法
int b = raf.read(); --> 读一个字节
(5)文件读写完成后一定要关闭,否则会造成资源浪费.
public class RafDemo {
public static void main(String[] args) throws IOException {
File demo = new File("demo");
if (!demo.exists()) {
demo.mkdir();
File file = new File("raf.txt");
if (!file.exists()) {
file.createNewFile();
}
// 指定随机读写操作
RandomAccessFile rw = new RandomAccessFile(file, "rw");
// 指针的位置
System.out.println(rw.getFilePointer());
rw.writeBytes("ABC");
System.out.println(rw.getFilePointer());
rw.write('B');
int n = 0x7fffffff;
// 用write方法每次只能写一个字节(8位),如果要把n写进去则需要写4次
rw.write(n >>> 24); //右移24位,把高8位写进去
rw.write(n >>> 16); //右移16位
rw.write(n >>> 8); //右移8位
rw.write(n);
System.out.println(rw.getFilePointer());
// 可以直接写一个int
rw.writeInt(n); //其底层就是做了上面的操作
String str = "中国";
byte[] bs = str.getBytes();
rw.write(bs);
System.out.println(rw.length());// 一个中文占两个字节长度
// 读文件,必须把指针移到头部
rw.seek(0);
// 一次性读取,把文件中的内容都读到字节数组中
byte[] buffer = new byte[(int) rw.length()];
int len;
rw.read(buffer);
System.out.println(Arrays.toString(buffer));
for (byte b : buffer) {
System.out.print(Integer.toHexString(b & 0xff) + " ");
}
System.out.println();
rw.seek(0);
while ((len = rw.read(buffer)) != -1) {
System.out.println(new String(buffer, 0, len));
}
// 关闭资源
rw.close();
} else {
demo.delete();
}
}
}输出结果:
0 3 8 18 [65, 66, 67, 66, 127, -1, -1, -1, 127, -1, -1, -1, -28, -72, -83, -27, -101, -67] 41 42 43 42 7f ff ff ff 7f ff ff ff e4 b8 ad e5 9b bd ABCB•���•���中国
(中间用write分段写的int类型乱码了,不知道是咋回事。。如果有大佬看到希望能告知是怎么回事,谢谢~)
随时随地看视频