1.文件编码
(1)直接新建文本,文本只认识ANSI编码格式。
(2)UTF-8:中文占3个字节、gdk:中文占2个字节、utf-16be(java是双字节编码):中文英文各占2个字节。
(3)将某种编码的字节序转换为字符串时,需要制定该编码,否则会出现乱码,不指定时使用默认工程编码。
import java.io.UnsupportedEncodingException; public class Encoding { private static void printByte(byte[]bytes) { for(byte b:bytes) {//把字节转换为int以16进制显示,int 4字节,前两个字节无效 System.out.print(Integer.toHexString(b&0xff)+" "); } System.out.println(); } public static void main(String[] args) { //默认工程编码 String str = "我是ABC"; byte[] bytes=str.getBytes(); printByte(bytes); try { bytes = str.getBytes("utf-8"); printByte(bytes); bytes = str.getBytes("utf-16be"); printByte(bytes); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // ce d2 ca c7 41 42 43 // e6 88 91 e6 98 af 41 42 43 // 62 11 66 2f 0 41 0 42 0 43 } }
2.File类文件使用
File只能用于表示文件(目录),不能访问文件内容。
遍历文件(目录含子目录)
import java.io.File; public class FileTest { private static int listDerictory(File dir) { if (!dir.exists()) { System.out.println("文件不存在"); return -1; } else if ( !dir.isDirectory()) { System.out.println("不是目录"); return 0; } File[] files = dir.listFiles(); if (files == null) { System.out.println(dir.getAbsolutePath()+"拒绝访问"); return -2; } //C:\Users\Administrator\AppData\Local\Application Data拒绝访问,出现空指针异常 for (File file : files) { if(file==null) { file=null; } if (file.isDirectory()) { listDerictory(file); } else { System.out.println(file.getAbsolutePath()); } } return 1; } public static void main(String[] args) { File file = new File("d:\\java_file\\you\\file"); if(!file.exists()) { file.mkdirs();//创建多级目录 } listDerictory(new File("C:\\Users\\")); listDerictory(new File("C:\\Users\\Administrator\\AppData\\Local\\Adobe")); //listDerictory(new File("C:\\Users\\")); } }
3.IO输入输出流
1)in.read()读取低8位,FileInputStream FileOutputStream字节操作
2)按字节读取不适合读取大文件,批量读取大文件效率较高。
3)DataOuputStream/DataInputStream
对“流”功能的扩展,可以更加方便的读取int,long,字符等类型数据
DataOutputStream
writeInt()/writeDouble()/writeUTF()
4)BufferedInputStream BufferedOutputSteam这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或者读取操作时,都会加上缓冲,这种流模式提高了IO得到性能,注意刷新缓冲区。
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class IOUtil{ /**public class IOUtil { /** * 读取指定文件内容,按照16进制输出到控制台 * 每隔10个byte输出换行 * @param fileName * @throws IOException */ public static void printHex(String fileName)throws IOException { FileInputStream in = new FileInputStream(fileName); int b; int i = 1 ; while( (b =in.read())!= -1) { System.out.print(Integer.toHexString(b)+" "); if(i%10==0) { System.out.println(); } i++; } in.close(); } public static void printHexByByteArray(String fileName) throws IOException { FileInputStream in= new FileInputStream(fileName); byte [] buf = new byte[20*1024]; /* 从in批量读取字节,放入buf这个字节数组中,从第0个位置开始放, 最多放buf.length个 返回的是读到的字节个数*/ int bytes=0; int j = 1; while((bytes=in.read(buf,0,buf.length))!=-1) { for (int i = 0 ; i < bytes;i++) {//&0xff:int有32位,byte有8位,为反正转换错误,除去前24位 System.out.print(Integer.toHexString(buf[i]&0xff)+" "); if( j++%10 == 0 ) { System.out.println(); } } } } /** * 进行文件的拷贝,利用带缓冲的字节流 * @param srcFile * @param destFile * @throws IOException */ public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{ if(!srcFile.exists()){ throw new IllegalArgumentException("文件:"+srcFile+"不存在"); } if(!srcFile.isFile()){ throw new IllegalArgumentException(srcFile+"不是文件"); } BufferedInputStream bis = new BufferedInputStream( new FileInputStream(srcFile)); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(destFile)); int c ; while((c = bis.read())!=-1){ bos.write(c); bos.flush();//刷新缓冲区 } bis.close(); bos.close(); } }
OutputStreamWriter 提供char流到byte流,按照编码处理
FileReader FileWriter 无法指定编码,很可能出现乱码
FileInputStream in = new FileInputStream("e:\\myutf8.txt"); InputStreamReader isr = new InputStreamReader(in,"utf-8");//默认项目的编码,操作的时候,要写文件本身的编码格式 FileOutputStream out = new FileOutputStream("e:\\my81.txt"); OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8"); /*int c ; while((c = isr.read())!=-1){ System.out.print((char)c); }*/ char[] buffer = new char[8*1024]; int c; <span style="color:#ff0000;">/*批量读取,放入buffer这个字符数组,从第0个位置开始放置,最多放buffer.length个 返回的是读到的字符的个数</span> */ while(( c = isr.read(buffer,0,buffer.length))!=-1){ String s = new String(buffer,0,c); System.out.print(s); osw.write(buffer,0,c); osw.flush(); } isr.close(); osw.close();
BufferedReader
BurreredWriter 不识别换行//单独写出换行操作
bw.newLine();//换行操作
PrintWriter
//对文件进行读写操作 BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream("e:\\javaio\\imooc.txt"))); /*BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream("e:\\javaio\\imooc3.txt")));*/ PrintWriter pw = new PrintWriter("e:\\javaio\\imooc4.txt"); //PrintWriter pw1 = new PrintWriter(outputStream,boolean autoFlush); String line ; while((line = br.readLine())!=null){ System.out.println(line);//一次读一行,并不能识别换行 /*bw.write(line); //单独写出换行操作 bw.newLine();//换行操作 bw.flush();*/ pw.println(line); pw.flush(); } br.close(); //bw.close(); pw.close();
5.对象的序列化和反序列化
1)对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化
2)序列化流(ObjectOutputStream),是过滤流--writeObject
反序列化流(ObjectInputStream)--readObject
3)序列化接口(Serializable)
对象必须实现序列化接口,才能进行序列化,否则出现异常
这个接口,没有任何方法,只是一个标准
4)transient关键字,指定默认不序列化,可以查看ArrayList源码查看transient的用法。
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException
5)父类实现了序列化,则子类可以直接序列化
对子类对象进行反序列化操作时,会递归调用其父类的构造函数
/*
* 对子类对象进行反序列化操作时,
* 如果其父类没有实现序列化接口
* 那么其父类的构造函数会被调用
*/
String file = "demo/obj.dat"; //1.对象的序列化 /*ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(file)); Student stu = new Student("10001", "张三", 20); oos.writeObject(stu); oos.flush(); oos.close();*/ ObjectInputStream ois = new ObjectInputStream( new FileInputStream(file)); Student stu = (Student)ois.readObject(); System.out.println(stu); ois.close();
package com.imooc.io; import java.io.Serializable; public class Student implements Serializable{ private String stuno; private String stuname; //该元素不会进行jvm默认的序列化,也可以自己完成这个元素的序列化 private transient int stuage; public Student(String stuno, String stuname, int stuage) { super(); this.stuno = stuno; this.stuname = stuname; this.stuage = stuage; } public String getStuno() { return stuno; } public void setStuno(String stuno) { this.stuno = stuno; } public String getStuname() { return stuname; } public void setStuname(String stuname) { this.stuname = stuname; } public int getStuage() { return stuage; } public void setStuage(int stuage) { this.stuage = stuage; } @Override public String toString() { return "Student [stuno=" + stuno + ", stuname=" + stuname + ", stuage=" + stuage + "]"; } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ s.defaultWriteObject();//把jvm能默认序列化的元素进行序列化操作 s.writeInt(stuage);//自己完成stuage的序列化 } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException{ s.defaultReadObject();//把jvm能默认反序列化的元素进行反序列化操作 this.stuage = s.readInt();//自己完成stuage的反序列化操作 } }
package com.imooc.io; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; public class FileDemo2 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub File file = new File("e:\\example"); /*String[] filenames = file.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { System.out.println(dir+"\\"+name); return name.endsWith("java"); } }); for (String string : filenames) { System.out.println(string); }*/ /*File[] files = file.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { // TODO Auto-generated method stub System.out.println(dir+"\\"+name); return false; } });*/ File[] files = file.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { // TODO Auto-generated method stub System.out.println(pathname); return false; } }); } }