文件编码
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类型乱码了,不知道是咋回事。。如果有大佬看到希望能告知是怎么回事,谢谢~)