@guoxs
2016-05-24T15:31:56.000000Z
字数 8669
阅读 2877
java
JAVA中的双字节编码(UTF-16be),中文和英文都占用两个字节。
toHexString(): 把字节转换成int以16进制的方式显示
当你的字节序列是某种编码时,如果想要把字节序列变成字符串,也需要用这种编码方式,否则会出现乱码。
文本文件就是字节序列,可以是任意编码的字节序列,如果在中文机器上直接创建文本文件,那么该文本文件只认识ANSI编码。
java.io.File类用于表示文件(目录)
File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问。
1.File file = new File("e:\\filename");File file1 = new File("e:"+File.separator()+"filename);自动创建分隔符File file2 = new File("e:\\io\\日记.txt");//自动创建没有的文件(File file2 = new File("e:\\io","日记.txt");if(!file.exist()) {file2 = createNewFile();}2.file.exist();//判断文件是否存在,会有异常,需要捕捉3.if(!file.exist()) {file.mkdir();//创建目录file.mkdirs();//创建多级目录file.delete();//删除目录4.file.isDirectory();//判断是否是目录5.file.isFile();//是否是一个文件6.常用的file对象的apiSystem.out.print(file);//打印toString对象,目录file.getAbsolutePath();//目录file.getName();//打印名字file.getParent();//父目录
遍历目录
public ststic void listDirectory(File dir) throws IOException{if(!dir.exists()){throw new IllegalArgumentException("目录" + dir + "不存在");}if(!dir.isDirectory()){throw new IllegalArgumentException(dir + "不是目录");}File[] files = dir.listFiles();if(files!=null && files.length > 0){for(File file : files){if(file.isDirectory()){listDirectory(file);}else{System.out.println(file);}}}}
RandomAccessFile java提供的对文件内容的访问,既可以读文件,也可以写文件。
RandomAccessFile支持随机访问文件,可以访问文件的任意位置
打开文件
有两种模式"rw"(读写) "r"(只读)
RandomAccessFile raf = new RandomeAccessFile(file,"rw")
文件指针,打开文件时指针在开头 pointer = 0;
InputStream抽象了应用程序读取数据的方式 OutputStream抽象了应用程序写出数据的方式
int b = in.read();//读取一个字节无符号填充到int**低八位**,高八位补0-1是 EOFin.read(byte[] buf);// 直接读到字节数组中in.read(byte[] buf,int start,int size) ;//读取数据到字节数组buf,从buf的start位置开始存放size长度的数据
out.write(int b); //写出一个byte到流,b的低8位out.write(byte[] buf); //将buf字节数组都写入到流out.write(byte[] buf,int start,int size)
*** 读取指定文件内容,按照16进制输出到控制台* 并且每输出10个byte换行* @param fileName* 单字节读取不适合大文件,大文件效率很低*/public static void printHex(String fileName) throws IOException{//把文件作为字节流进行读操作FileInputStream in = new FileInputStream(fileName);int b ;int i = 1;while((b = in.read())!=-1){if(b <= 0xf){//单位数前面补0System.out.print("0");}System.out.print(Integer.toHexString(b)+" ");if(i++%10==0){System.out.println();}}in.close();}
/*** 批量读取,对大文件而言效率高,也是我们最常用的读文件的方式* @param fileName* @throws IOException*/public static void printHexByByteArray(String fileName)throws IOException{FileInputStream in = new FileInputStream(fileName);byte[] buf = new byte[8 * 1024];/*从in中批量读取字节,放入到buf这个字节数组中,* 从第0个位置开始放,最多放buf.length个* 返回的是读到的字节的个数*//*int bytes = in.read(buf,0,buf.length);//一次性读完,说明字节数组足够大int j = 1;for(int i = 0; i < bytes;i++){System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");if(j++%10==0){System.out.println();}}*/int bytes = 0;int j = 1;while((bytes = in.read(buf,0,buf.length))!=-1){for(int i = 0 ; i < bytes;i++){/*byte类型为8位,int类型为32位,为了避免数据转换错误,通过 & 0xff将高24位清零*/System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");if(j++%10==0){System.out.println();}}}in.close();}
文件拷贝操作:
/*效率最高*/public static void copyFile(File srcFile,File destFile)throws IOException{if(!srcFile.exists()){throw new IllegalArgumentException("文件:"+srcFile+"不存在");}if(!srcFile.isFile()){throw new IllegalArgumentException(srcFile+"不是文件");}FileInputStream in = new FileInputStream(srcFile);FileOutputStream out = new FileOutputStream(destFile);byte[] buf = new byte[8*1024];int b ;while((b = in.read(buf,0,buf.length))!=-1){out.write(buf,0,b);out.flush();//最好加上}in.close();out.close();}
public static void main(String[] args) throws IOException {// TODO Auto-generated method stub//如果该文件不存在,则直接创建,如果存在,删除后创建FileOutputStream out = new FileOutputStream("demo/out.dat");out.write('A');//写出了'A'的低八位out.write('B');//写出了'B'的低八位int a = 10;//write只能写八位,那么写一个int需要些4次每次8位out.write(a >>> 24);out.write(a >>> 16);out.write(a >>> 8);out.write(a);byte[] gbk = "中国".getBytes("gbk");out.write(gbk);out.close();}}
DataOutputStream writeInt()/writeDouble()/writeUTF()
public class DosDemo {public static void main(String[] args) throws IOException {String file = "demo/dos.dat";DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));dos.writeInt(10);dos.writeInt(-10);dos.writeLong(10l);dos.writeDouble(10.5);//采用utf-8编码写出dos.writeUTF("中国");//采用utf-16be编码写出dos.writeChars("中国");dos.close();}}
FileOutputStream--->write()方法相当于一滴一滴地把水“转移”过去 DataOutputStream-->writeXxx()方法会方便一些,相当于一瓢一瓢把水“转移”过去 BufferedOutputStream--->write方法更方便,相当于一飘一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高了
/*** 进行文件的拷贝,利用带缓冲的字节流* @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();}/*** 单字节,不带缓冲进行文件拷贝,效率最低* @param srcFile* @param destFile* @throws IOException*/public static void copyFileByByte(File srcFile,File destFile)throws IOException{if(!srcFile.exists()){throw new IllegalArgumentException("文件:"+srcFile+"不存在");}if(!srcFile.isFile()){throw new IllegalArgumentException(srcFile+"不是文件");}FileInputStream in = new FileInputStream(srcFile);FileOutputStream out = new FileOutputStream(destFile);int c ;while((c = in.read())!=-1){out.write(c);out.flush();}in.close();out.close();}
java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)
文件是byte byte byte ...的数据序列
文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储结果
public static void main(String[] args)throws IOException {FileInputStream in = new FileInputStream("e:\\javaio\\imoocutf8.txt");InputStreamReader isr = new InputStreamReader(in,"utf-8");//默认项目的编码,操作的时候,要写文件本身的编码格式FileOutputStream out = new FileOutputStream("e:\\javaio\\imoocutf81.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;/*批量读取,放入buffer这个字符数组,从第0个位置开始放置,最多放buffer.length个返回的是读到的字符的个数*/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();}
字符的处理,一次处理一个字符
字符的底层任然是基本的字节序列
字符流的基本实现
InputStreamReader完成byte流解析为char流,按照编码解析
OutputStreamWriter提供char流到byte流,按照编码处理
FileReader/FileWriter
public static void main(String[] args) throws IOException{FileReader fr = new FileReader("e:\\javaio\\imooc.txt");FileWriter fw = new FileWriter("e:\\javaio\\imooc2.txt");//FileWriter fw = new FileWriter("e:\\javaio\\imooc2.txt",true);//追加char[] buffer = new char[2056];int c ;while((c = fr.read(buffer,0,buffer.length))!=-1){fw.write(buffer,0,c);fw.flush();}fr.close();fw.close();}
public static void main(String[] args) throws IOException{//对文件进行读写操作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();}
对象必须实现序列化接口 ,才能进行序列化,否则将出现异常这个接口,接口没有任何方法,只是一个标准
public static void main(String[] args) throws Exception{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();}
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOExceptionprivate void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException
分析ArrayList源码中序列化和反序列化的问题
- 序列化中 子类和父类构造函数的调用问题
对子类对象进行反序列化操作时, 如果其父类没有实现序列化接口,那么其父类的构造函数会被调用