1.编码
public class EncodeDemo { public static void main(String[] args) { String s = "聪123"; byte[] b1 = s.getBytes(); //转换成字节序列用的是项目默认的编码 for (byte b : b1) { //把字节转换成以16进制的方式显示 System.out.print(Integer.toHexString(b & 0xFF) + " "); } System.out.println(); try { //gbk编码中文占用2个字节,英文占用1个字节 byte[] b2 = s.getBytes("gbk"); for (byte b : b2) { System.out.print(Integer.toHexString(b & 0xff) + " "); } System.out.println(); //utf-8编码中文占用3个字节,英文占用1个字节 byte[] b3 = s.getBytes("utf-8"); for (byte b : b3) { System.out.print(Integer.toHexString(b & 0xff) + " "); } System.out.println(); //java是双字节编码 utf-16be编码 //utf-16中文占用三个字节,英文占用2个字节 byte[] b4 = s.getBytes("utf-16be"); for (byte b : b4) { System.out.print(Integer.toHexString(b & 0xff) + " "); } System.out.println(); /** * 当你的字节序列是某种编码时,这个时候想要把字节序列变成字符串,也需要这种编码方式,否则会出现乱码 */ String s1 = new String(b4); System.out.println(s1); String s2 = new String(b4, "utf-16be"); System.out.println(s2); /** * 文本文件就是字节序列,可以是任意的字节序列,如果我们在中文机器上创建文本文件,那么这个机器只认识ansi编码 * 联通,联这是一种巧合,他们正好符合了utf-8编码规则 */ } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }
2.File
File类用于表示文件(目录)的信息(名称,大小等),不能用于文件内容的访问
public class FileDemo { public static void main(String[] args) { /** * 创建文件夹 */ //了解构造函数插帮助 File file = new File("/Users/apple/test/联"); //是否是个目录 System.out.println(file.isDirectory()); //是否是个文件 System.out.println(file.isFile()); System.out.println(file.exists()); if (!file.exists()){ file.mkdir(); } else { file.delete(); } /** * 创建文件 */ File file1 = new File("/Users/apple/test/联想.txt"); try { if (!file1.exists()) { file1.createNewFile(); } else { file1.delete(); } } catch (IOException e) { e.printStackTrace(); } /** * 创建子目录 */ File file2 = new File("/Users/apple/test", "111.txt"); try { if (!file1.exists()) { file2.createNewFile(); } else { //file2.delete(); } } catch (IOException e) { e.printStackTrace(); } //常用方法 System.out.println(file2); System.out.println(file2.getAbsolutePath()); System.out.println(file2.getName()); System.out.println(file2.getParent()); //file.mkdirs(); } }
3.FileUtil
public class FileUtil { /** * 列出置顶目录下指定目录的所有文件 * @param file * @throws Exception */ public static void listDirectory(File file) throws Exception { if (!file.exists()) { throw new IllegalArgumentException("文件不存在"); } if (!file.isDirectory()) { throw new IllegalArgumentException("不是目录"); } String[] filename = file.list(); for (String s : filename) { System.out.println(file + "/" + s); } //遍历子目录下的内容,就需要构造file对象做递归操作 File[] files = file.listFiles(); //返回的是子目录下的对象 if (files != null && files.length > 0) { for (File file1 : files) { if (file1.isDirectory()) { //递归 } } } } }
4.RandomAccessFile
java提供的对文件内容对访问,既可以读文件,也可以写文件,支持随机读取文件,可以访问文件的任意位置
public static void main(String[] args) throws IOException { File file = new File("demo"); if (!file.exists()) { file.mkdirs(); } File file1 = new File(file, "raf.dat"); if (!file1.exists()) { file1.createNewFile(); } //rw:读写 RandomAccessFile randomAccessFile = new RandomAccessFile(file1, "rw"); System.out.println(randomAccessFile.getFilePointer()); randomAccessFile.write('a'); System.out.println(randomAccessFile.getFilePointer()); randomAccessFile.write('b'); int i = 0x7fffffff; //用write方法每次只能写一个字节,如果想要把i写进去就需要4次 randomAccessFile.write(i >>> 24); randomAccessFile.write(i >>> 16); randomAccessFile.write(i >>> 8); randomAccessFile.write(i); System.out.println(randomAccessFile.getFilePointer()); randomAccessFile.writeInt(i); String s = "中"; byte[] gbk = s.getBytes("utf-8"); randomAccessFile.write(gbk); System.out.println(randomAccessFile.length()); //读文件,必须把指针移到头部 randomAccessFile.seek(0); //一次性读取,把文件中对内容都读到字节数组中 byte[] b = new byte[(int)randomAccessFile.length()]; randomAccessFile.read(b); }
5.io流
5.1 字节流
5.1.1 inputStream(读)
int b = in.read(); //读取一个字节无符号填充到int的低八位,-1结束
in.read(byte[] b);
in.read(byte[] b, int start, int size);
5.1.2 outputStream(写)
out.write(int b); //写出一个byte到流,写到是b到低八位
out.read(byte[] b); //将b字节数组写入到流
out.read(byte[] b, int start, int size);
5.1.3 FileInputStream 具体实现了在文件上读的操作
/** * 读取指定文件内容,按照16进制输出到控制台 * @param fileName */ public static void printHex(String fileName) { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(fileName); int b; int i = 1; while ((b = fileInputStream.read()) != -1) { System.out.print(Integer.toHexString(b) + ""); if (i++ % 10 == 0) { System.out.println(); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fileInputStream != null) { fileInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
fileInputStream = new FileInputStream(fileName);
byte[] buf = new byte[20 * 1024];
// 从fileInputStream中批量读取字节,放入到buf这个数组中,从第0个位置开始放,最多放buf.length,返回的是读到字节的个数 int bytes = fileInputStream.read(buf, 0, buf.length); //一次性读完,说明字节的数组足够大 int j = 1; for (int i = 0; i < bytes; i++){ if (buf[i] <= 0xf) { System.out.print("0"); } System.out.print(Integer.toHexString(buf[i]) + " "); if (j++ % 10 == 0) { System.out.println(); } }
int j = 1; int bytes = 0; while ((bytes = fileInputStream.read(buf, 0, buf.length)) != -1) { for (int i = 0; i < bytes; i++){ if (buf[i] <= 0xf) { System.out.print("0"); } System.out.print(Integer.toHexString(buf[i]) + " "); if (j++ % 10 == 0) { System.out.println(); } } }
5.1.4 FileOutputStream 具体实现了在文件上写的操作
public static void main(String[] args) throws IOException { FileOutputStream fileOutputStream = null; try { //如果该文件不存在,则直接创建,如果存在,则删除后创建 fileOutputStream = new FileOutputStream("demo/raf.dat"); fileOutputStream.write('a'); fileOutputStream.write('b'); int a = 10; //write 只能写八位,那么写一个int需要写4次 fileOutputStream.write(a >>> 24); fileOutputStream.write(a >>> 16); fileOutputStream.write(a >>> 8); fileOutputStream.write(a); byte[] gbk = "中国".getBytes("gbk"); fileOutputStream.write(gbk); fileOutputStream.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (fileOutputStream != null) { fileOutputStream.close(); } } }
5.1.4 文件复制
/** * 文件复制 * @param srcFile * @param destFile */ public static void copyFile(File srcFile, File destFile) { if (!srcFile.exists()) { throw new IllegalArgumentException("参数问题,文件不存在"); } if (!srcFile.isFile()) { throw new IllegalArgumentException("不是文件"); } FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { fileInputStream = new FileInputStream(srcFile); fileOutputStream = new FileOutputStream(destFile); byte[] buf = new byte[8 * 1024]; int b; while ((b = fileInputStream.read(buf, 0, buf.length)) != -1){ fileOutputStream.write(buf, 0, b); } fileOutputStream.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fileInputStream != null) { fileInputStream.close(); } if (fileOutputStream != null) { fileOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
5.2.1 DataInputStream/DataOutputStream 对流功能对拓展,可以更加方便对读取int,long,字符等类型等数据
writeInt(), writeDouble(), writeUTF()
/** * 读 * @param fileName */ public static void write(String fileName) { DataOutputStream dataOutputStream = null; try { dataOutputStream = new DataOutputStream(new FileOutputStream(fileName)); dataOutputStream.writeInt(10); //采用utf-8 dataOutputStream.writeUTF("中国"); //采用utf-16be编码写出 dataOutputStream.writeChars("中国"); dataOutputStream.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (dataOutputStream != null) { dataOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
/** * 写 * @param fileName */ public static void read(String fileName) { DataInputStream dataInputStream = null; try { dataInputStream = new DataInputStream(new FileInputStream(fileName)); int i = dataInputStream.readInt(); System.out.println(i); String s = dataInputStream.readUTF(); System.out.println(s); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (dataInputStream != null) { dataInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
6. 缓冲流
6.1 BufferInputStream/BufferOutputStream 这两个流类为io提供了带缓冲区带操作,一般打开文件进行写入或者读取操作时,都会加上缓存,这种提升了输入/输出的性能
/** * 利用带缓冲流进行文件带拷贝 * @param srcFile * @param destFile */ public static void copyFileByBuffer(File srcFile, File destFile) { if (!srcFile.exists()) { throw new IllegalArgumentException("文件不存在"); } if (!srcFile.isFile()) { throw new IllegalArgumentException("不是文件"); } BufferedInputStream bufferedInputStream = null; BufferedOutputStream bufferedOutputStream = null; try { bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFile)); bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destFile)); int c; while ((c = bufferedInputStream.read()) != -1) { bufferedOutputStream.write(c); } bufferedOutputStream.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (bufferedInputStream != null) { bufferedInputStream.close(); } if (bufferedOutputStream != null) { bufferedOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }