[关闭]
@guoxs 2016-05-24T15:31:56.000000Z 字数 8669 阅读 2384

Java IO流

java


编码

JAVA中的双字节编码(UTF-16be),中文和英文都占用两个字节。

toHexString(): 把字节转换成int以16进制的方式显示

当你的字节序列是某种编码时,如果想要把字节序列变成字符串,也需要用这种编码方式,否则会出现乱码。

文本文件就是字节序列,可以是任意编码的字节序列,如果在中文机器上直接创建文本文件,那么该文本文件只认识ANSI编码。

Files类常用API

java.io.File类用于表示文件(目录)
File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问。

  1. 1.File file = new File("e:\\filename");
  2. File file1 = new File("e:"+File.separator()+"filename);自动创建分隔符
  3. File file2 = new File("e:\\io\\日记.txt");//自动创建没有的文件
  4. (File file2 = new File("e:\\io","日记.txt");
  5. if(!file.exist()) {
  6. file2 = createNewFile();
  7. }
  8. 2.file.exist();//判断文件是否存在,会有异常,需要捕捉
  9. 3.if(!file.exist()) {
  10. file.mkdir();//创建目录
  11. file.mkdirs();//创建多级目录
  12. file.delete();//删除目录
  13. 4.file.isDirectory();//判断是否是目录
  14. 5.file.isFile();//是否是一个文件
  15. 6.常用的file对象的api
  16. System.out.print(file);//打印toString对象,目录
  17. file.getAbsolutePath();//目录
  18. file.getName();//打印名字
  19. file.getParent();//父目录

遍历目录

  1. public ststic void listDirectory(File dir) throws IOException{
  2. if(!dir.exists()){
  3. throw new IllegalArgumentException("目录" + dir + "不存在");
  4. }
  5. if(!dir.isDirectory()){
  6. throw new IllegalArgumentException(dir + "不是目录");
  7. }
  8. File[] files = dir.listFiles();
  9. if(files!=null && files.length > 0){
  10. for(File file : files){
  11. if(file.isDirectory()){
  12. listDirectory(file);
  13. }else{
  14. System.out.println(file);
  15. }
  16. }
  17. }
  18. }

RandomAccessFile基本操作

RandomAccessFile java提供的对文件内容的访问,既可以读文件,也可以写文件。
RandomAccessFile支持随机访问文件,可以访问文件的任意位置

IO流

字节流

  1. int b = in.read();//读取一个字节无符号填充到int**低八位**,高八位补0-1是 EOF
  2. in.read(byte[] buf);// 直接读到字节数组中
  3. in.read(byte[] buf,int start,int size) ;//读取数据到字节数组buf,从buf的start位置开始存放size长度的数据
  1. out.write(int b); //写出一个byte到流,b的低8位
  2. out.write(byte[] buf); //将buf字节数组都写入到流
  3. out.write(byte[] buf,int start,int size)
  1. **
  2. * 读取指定文件内容,按照16进制输出到控制台
  3. * 并且每输出10byte换行
  4. * @param fileName
  5. * 单字节读取不适合大文件,大文件效率很低
  6. */
  7. public static void printHex(String fileName) throws IOException{
  8. //把文件作为字节流进行读操作
  9. FileInputStream in = new FileInputStream(fileName);
  10. int b ;
  11. int i = 1;
  12. while((b = in.read())!=-1){
  13. if(b <= 0xf){
  14. //单位数前面补0
  15. System.out.print("0");
  16. }
  17. System.out.print(Integer.toHexString(b)+" ");
  18. if(i++%10==0){
  19. System.out.println();
  20. }
  21. }
  22. in.close();
  23. }
  1. /**
  2. * 批量读取,对大文件而言效率高,也是我们最常用的读文件的方式
  3. * @param fileName
  4. * @throws IOException
  5. */
  6. public static void printHexByByteArray(String fileName)throws IOException{
  7. FileInputStream in = new FileInputStream(fileName);
  8. byte[] buf = new byte[8 * 1024];
  9. /*从in中批量读取字节,放入到buf这个字节数组中,
  10. * 从第0个位置开始放,最多放buf.length个
  11. * 返回的是读到的字节的个数
  12. */
  13. /*int bytes = in.read(buf,0,buf.length);//一次性读完,说明字节数组足够大
  14. int j = 1;
  15. for(int i = 0; i < bytes;i++){
  16. System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");
  17. if(j++%10==0){
  18. System.out.println();
  19. }
  20. }*/
  21. int bytes = 0;
  22. int j = 1;
  23. while((bytes = in.read(buf,0,buf.length))!=-1){
  24. for(int i = 0 ; i < bytes;i++){
  25. /*byte类型为8位,int类型为32位,为了避免数据转换错误,通过 & 0xff将高24位清零*/
  26. System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");
  27. if(j++%10==0){
  28. System.out.println();
  29. }
  30. }
  31. }
  32. in.close();
  33. }

文件拷贝操作:

  1. /*效率最高*/
  2. public static void copyFile(File srcFile,File destFile)throws IOException{
  3. if(!srcFile.exists()){
  4. throw new IllegalArgumentException("文件:"+srcFile+"不存在");
  5. }
  6. if(!srcFile.isFile()){
  7. throw new IllegalArgumentException(srcFile+"不是文件");
  8. }
  9. FileInputStream in = new FileInputStream(srcFile);
  10. FileOutputStream out = new FileOutputStream(destFile);
  11. byte[] buf = new byte[8*1024];
  12. int b ;
  13. while((b = in.read(buf,0,buf.length))!=-1){
  14. out.write(buf,0,b);
  15. out.flush();//最好加上
  16. }
  17. in.close();
  18. out.close();
  19. }
  1. public static void main(String[] args) throws IOException {
  2. // TODO Auto-generated method stub
  3. //如果该文件不存在,则直接创建,如果存在,删除后创建
  4. FileOutputStream out = new FileOutputStream("demo/out.dat");
  5. out.write('A');//写出了'A'的低八位
  6. out.write('B');//写出了'B'的低八位
  7. int a = 10;//write只能写八位,那么写一个int需要些4次每次8位
  8. out.write(a >>> 24);
  9. out.write(a >>> 16);
  10. out.write(a >>> 8);
  11. out.write(a);
  12. byte[] gbk = "中国".getBytes("gbk");
  13. out.write(gbk);
  14. out.close();
  15. }
  16. }
  1. public class DosDemo {
  2. public static void main(String[] args) throws IOException {
  3. String file = "demo/dos.dat";
  4. DataOutputStream dos = new DataOutputStream(
  5. new FileOutputStream(file));
  6. dos.writeInt(10);
  7. dos.writeInt(-10);
  8. dos.writeLong(10l);
  9. dos.writeDouble(10.5);
  10. //采用utf-8编码写出
  11. dos.writeUTF("中国");
  12. //采用utf-16be编码写出
  13. dos.writeChars("中国");
  14. dos.close();
  15. }
  16. }
  1. /**
  2. * 进行文件的拷贝,利用带缓冲的字节流
  3. * @param srcFile
  4. * @param destFile
  5. * @throws IOException
  6. */
  7. public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{
  8. if(!srcFile.exists()){
  9. throw new IllegalArgumentException("文件:"+srcFile+"不存在");
  10. }
  11. if(!srcFile.isFile()){
  12. throw new IllegalArgumentException(srcFile+"不是文件");
  13. }
  14. BufferedInputStream bis = new BufferedInputStream(
  15. new FileInputStream(srcFile));
  16. BufferedOutputStream bos = new BufferedOutputStream(
  17. new FileOutputStream(destFile));
  18. int c ;
  19. while((c = bis.read())!=-1){
  20. bos.write(c);
  21. bos.flush();//一定要加,刷新缓冲区
  22. }
  23. bis.close();
  24. bos.close();
  25. }
  26. /**
  27. * 单字节,不带缓冲进行文件拷贝,效率最低
  28. * @param srcFile
  29. * @param destFile
  30. * @throws IOException
  31. */
  32. public static void copyFileByByte(File srcFile,File destFile)throws IOException{
  33. if(!srcFile.exists()){
  34. throw new IllegalArgumentException("文件:"+srcFile+"不存在");
  35. }
  36. if(!srcFile.isFile()){
  37. throw new IllegalArgumentException(srcFile+"不是文件");
  38. }
  39. FileInputStream in = new FileInputStream(srcFile);
  40. FileOutputStream out = new FileOutputStream(destFile);
  41. int c ;
  42. while((c = in.read())!=-1){
  43. out.write(c);
  44. out.flush();
  45. }
  46. in.close();
  47. out.close();
  48. }

字符流

  1. public static void main(String[] args)throws IOException {
  2. FileInputStream in = new FileInputStream("e:\\javaio\\imoocutf8.txt");
  3. InputStreamReader isr = new InputStreamReader(in,"utf-8");//默认项目的编码,操作的时候,要写文件本身的编码格式
  4. FileOutputStream out = new FileOutputStream("e:\\javaio\\imoocutf81.txt");
  5. OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
  6. /*int c ;
  7. while((c = isr.read())!=-1){
  8. System.out.print((char)c);
  9. }*/
  10. char[] buffer = new char[8*1024];
  11. int c;
  12. /*批量读取,放入buffer这个字符数组,从第0个位置开始放置,最多放buffer.length个
  13. 返回的是读到的字符的个数
  14. */
  15. while(( c = isr.read(buffer,0,buffer.length))!=-1){
  16. String s = new String(buffer,0,c);
  17. System.out.print(s);
  18. osw.write(buffer,0,c);
  19. osw.flush();
  20. }
  21. isr.close();
  22. osw.close();
  23. }
  1. public static void main(String[] args) throws IOException{
  2. FileReader fr = new FileReader("e:\\javaio\\imooc.txt");
  3. FileWriter fw = new FileWriter("e:\\javaio\\imooc2.txt");
  4. //FileWriter fw = new FileWriter("e:\\javaio\\imooc2.txt",true);//追加
  5. char[] buffer = new char[2056];
  6. int c ;
  7. while((c = fr.read(buffer,0,buffer.length))!=-1){
  8. fw.write(buffer,0,c);
  9. fw.flush();
  10. }
  11. fr.close();
  12. fw.close();
  13. }
  1. public static void main(String[] args) throws IOException{
  2. //对文件进行读写操作
  3. BufferedReader br = new BufferedReader(
  4. new InputStreamReader(
  5. new FileInputStream("e:\\javaio\\imooc.txt")));
  6. /*BufferedWriter bw = new BufferedWriter(
  7. new OutputStreamWriter(
  8. new FileOutputStream("e:\\javaio\\imooc3.txt")));*/
  9. PrintWriter pw = new PrintWriter("e:\\javaio\\imooc4.txt");
  10. //PrintWriter pw1 = new PrintWriter(outputStream,boolean autoFlush);
  11. String line ;
  12. while((line = br.readLine())!=null){
  13. System.out.println(line);//一次读一行,并不能识别换行
  14. /*bw.write(line);
  15. //单独写出换行操作
  16. bw.newLine();//换行操作
  17. bw.flush();*/
  18. pw.println(line);
  19. pw.flush();
  20. }
  21. br.close();
  22. //bw.close();
  23. pw.close();
  24. }

序列化与基本类型序列化

对象的序列化,反序列化

  1. public static void main(String[] args) throws Exception{
  2. String file = "demo/obj.dat";
  3. //1.对象的序列化
  4. /*ObjectOutputStream oos = new ObjectOutputStream(
  5. new FileOutputStream(file));
  6. Student stu = new Student("10001", "张三", 20);
  7. oos.writeObject(stu);
  8. oos.flush();
  9. oos.close();*/
  10. ObjectInputStream ois = new ObjectInputStream(
  11. new FileInputStream(file));
  12. Student stu = (Student)ois.readObject();
  13. System.out.println(stu);
  14. ois.close();
  15. }
  1. private void writeObject(java.io.ObjectOutputStream s)
  2. throws java.io.IOException
  3. private void readObject(java.io.ObjectInputStream s)
  4. throws java.io.IOException, ClassNotFoundException

分析ArrayList源码中序列化和反序列化的问题
- 序列化中 子类和父类构造函数的调用问题

对子类对象进行反序列化操作时, 如果其父类没有实现序列化接口,那么其父类的构造函数会被调用

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注