JAVA IO 专题
来源:互联网 发布:微信营销软件 编辑:程序博客网 时间:2024/05/28 11:29
首先看一下常用的几种编码方式
public class EncodeDemo{public static void main(String[] agrs)throws IOException{String s="中国ABC";byte[] byte1=s.getBytes(); //默认采用项目的UTF-8编码byte[] byte2=s.getBytes("GBK");//显示指定编码方式为GBKbyte[] byte3=s.getBytes("UTF-16be"); for(byte b:byte1){/** * 把字节转换成int以十六进制的方式显示 * 默认采用项目的编码,此处使用UTF-8,得到的结果为e4 b8 ad e5 9b bd 41 42 43 *可见采用utf-8编码,中文占用三个字节,英文占用一个字节 */System.out.print(Integer.toHexString(b & 0xff)+" ");} System.out.println(); for(byte b:byte2){/** * 把字节转换成int以十六进制的方式显示,高位三个字节补0 * 显示指定编码方式为GBK,,得到的结果为d6 d0 b9 fa 41 42 43 * 可见采用GBK编码,中文占用三个字节,英文占用一个字节 */System.out.print(Integer.toHexString(b & 0xff)+" ");} System.out.println(); for(byte b:byte3){/** * java是双字节编码utf-16be * 把字节转换成int以十六进制的方式显示,高位三个字节补0 * 显示指定编码方式为UTF-16be,得到的结果为4e 2d 56 fd 0 41 0 42 0 43 * 可见采用UTF-16be编码,中文占用两个字节,英文也占用两个字节 */System.out.print(Integer.toHexString(b & 0xff)+" ");} System.out.println(); /* * 字节数组转换成字符串,必须与之前的转换采用相同的编码方式,不然会出现乱码 */ String s1 = new String(byte1); System.out.println(s1); //中国ABC,采用默认的项目编码格式 String s2 = new String(byte2); System.out.println(s2);//�й� 出现乱码,因为byte2用的是GBK编码,转换成字符串时用得默认的UTF-8 String s3 = new String(byte2,"GBK"); System.out.println(s3);//中国ABC ,显示指定GBK编码方式,便不会出现乱码}}
通过这个例子可以看出,常用的编码方式有UTF-8,汉字编码站三个字节,英文字母编码占用1个字节;GBK编码,中文占用两个字节,英文字母占用一个字节;java 是双字节UTF-16be编码,这种编码方式中文和英文都占用两个字节,在字符串与字节进行转换时,默认采用项目指定的编码方式,还要注意双向转换时,编码方式要相同,不然会出现乱码。
File类的使用:
java.io.File类用于表示文件或目录,它只用于表示文件或目录的信息(名称,大小等),不能用于文件内容的访问
public class FileDemo {public static void main(String[] args){/* * 了解几种常用的构造函数 */File file = new File("F:\\开心");//注意:路径要使用双斜杠或者反斜杠System.out.println(file);File file2 = new File("F:\\开心","开心1.txt");File file3 = new File(file2,"开心2.txt");if(!file.exists()){/* * 如果目录不存在,则创建目录,mkdirs()可用于创建多级目录 * file.createNewFile()用于创建文件 */file.mkdir(); }else{file.delete();}/* * File类的几种常用API */System.out.println(file.isFile());System.out.println(file.isDirectory());System.out.println(file); //打印文件的路径System.out.println(file.getAbsolutePath());//同样打印文件的完整路径System.out.println(file.getName());//打印文件或目录的名字System.out.println(file.getParent());//打印文件或目录的父目录System.out.println(file.getParentFile());}}
以上介绍FIle类创建对象的几种方式以及常用API
包装对对文件或目录的几种常用操作,如过滤,遍历等
/<span style="font-family: Arial, Helvetica, sans-serif;">/包装File的一些常用操作,如过滤,遍历</span>
public class FileUtil{/* * 遍历目录下的所有文件和目录 */public static void listDirectory(File dir)throws IOException{if(!dir.exists()){throw new IllegalArgumentException("目录"+dir+"不存在");}if(!dir.isDirectory()){throw new IllegalArgumentException(dir+"不是目录");}/*String[] fileNames = dir.list(); //返回字符串数组,直接子的名称,不包含子目录下的内容for (String string : fileNames){System.out.println(string);}*/File[] files = dir.listFiles();if(files!=null && files.length>0){for (File file : files){System.out.println(file);if(file.isDirectory()) //递归遍历{listDirectory(file);}}}} }
RandomAccessFile类:提供了对文件内容的访问,既可以读文件,也可以写文件。它提供对文件的随机访问,可以访问文件的任意位置
1>文件模式
java文件,在硬盘上是byte byte byte...存储的,是数据的集合
2>打开文件
打开文件有两种模式 “rw” 读写操作 “r” 只读操作
RandomAccessFile raf = new RandomAccessFile (file , "wr"),RandomAccessFile的随机访问是依靠文件指针实现的,打开文 件的默认指针位置prointer=0,即在文件的开头。读写操作会伴随着指针位置的移动。
3>写方法
raf.write(int), ----->只写一个字节,同时指针只想下一个位置,准备再次进行写操作
4>读方法
raf.read()---->只写一个字节
5>文件读写完成后一定要关闭,不然会发生意想不到的错误
public class RandomAccessFileDemo {public static void main(String[] args)throws IOException{File file = new File("demo");if(!file.exists()){file.createNewFile();}RandomAccessFile raf = new RandomAccessFile(file, "rw");System.out.println(raf.getFilePointer()); //获取文件指针的位置,0raf.write('A');//只写入一个字节System.out.println(raf.getFilePointer()); //1int i = 0x7fffffff;//最大的整数//用write方法,每次只能写一个字节,写一个int需要写4次raf.write(i>>24);raf.write(i>>16);raf.write(i>>8);raf.write(i);//也可以直接写一个int,时机底层也是进行四次写操作raf.writeInt(i);System.out.println(raf.getFilePointer());String s="中国";byte[] byte1 = s.getBytes("gbk");raf.write(byte1);System.out.println(raf.length()); //文件的长度 13//读文件必须把文件指针移到文件的开始,也可以移到指定的位置进行读取raf.seek(0);byte[] buf = new byte[(int) raf.length()];raf.read(buf) ;//批量读取System.out.println(Arrays.toString(buf));//以十六进制的方式输出for (byte b : buf){System.out.print(Integer.toHexString(b&0xff)+" ");}raf.close();}}
IO流(输入流,输出流)
字节流:
1>
InputStream 抽象了应用程序读取数据的方式,读到程序中为输入
OutputStream 抽象了应用程序写出数据的方式
2>
EOF =End 读到-1就读到了文件的结尾
3>输入流基本方法
int b = in.read(); 读取一个字节填充到int低八位
in.read(byte[] buf) ; 批量读取字节到字节数组中
in.read(byte[] buf , int start ,int size)
4>输出流基本方法
out.write(int b) // 写出int b 的低八位到流
out.write(byte[] b) ; 写出字节数组中的全部字节
out.write(byte[] b , int start ,int size) //从下表start开始,写出size个字节
5>具体实现类
FileInputStream --->具体实现了在文件中读取数据
/* * 读取指定文件内容,以十六进制输出到控制台 * 每读取10个字节换行, * 单字节读取,不适合大文件,效率很低 */public class IOUtil{public static void printHex(String filename)throws IOException{FileInputStream fis = new FileInputStream(filename);int b;int i=1;while((b=fis.read())!=-1) //每次只读取一个字节{if(b<=0xf)System.out.print("0"); //如果只有第四位,则在前面补零System.out.print(Integer.toHexString(b)+" ");if(i++%10 == 0){System.out.println();}}fis.close();}/* * 批量读取,大区大文件时效率很高 * 常用的文件读取方式 */public static void printHexByByteArray(String filename)throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buffer = new byte[10*1024];/* * 从fis中批量读取字节,放入到buf中,从第0个位置开始放,最多放buffer.length个字节 * 返回的是读取字节的个数 * 为了防止一次读不完一个文件,所以用到while循环,读到文件结尾为止 */int n;while((n=fis.read(buffer, 0, buffer.length))!=-1){int k=1;for (int i=0;i<n;i++){if(buffer[i]<=0xf)System.out.print("0");System.out.print(Integer.toHexString(buffer[i]&0xff)+" ");if(k++%10 == 0)System.out.println();}}System.out.println();fis.close();}/* * 文件的copy */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[10*1024];int n;while((n=in.read(buf, 0, buf.length))!=-1){out.write(buf, 0, n);}}
FileOutputStream --->继承了OutputStream,具体实现了向文件中写入byte数据的方法
public class FileOutputStreamDemo1 {public static void main(String[] args)throws IOException{//如果文件不存在,则创建该文件,如果该文件存在,则删除后再重新创建FileOutputStream fos = new FileOutputStream("demo.dat",true);/* * 如果文件不存在,则创建该文件,如果文件存在,则以追加的方式向文件中写数据 * FileOutputStream fos = new FileOutputStream("demo.dat","true"); */fos.write('A'); //写一个字节String s = "中国";byte[] b = s.getBytes();fos.write(b); //写一个字节数组fos.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[10*1024];int n;while((n=in.read(buf, 0, buf.length))!=-1){out.write(buf, 0, n);}}}
DataInputStrean 和 DataOutputStrean 采用装饰模式,底层包装一个字节的读取操作
out.writeInt(10);out.writeInt(-10);out.writeLong(10l);out.writeDouble(1.11);out.writeUTF("中国");out.writeChars("中国人");DataInputStrean中有与之对应的read操作
带缓冲的字节流
BufferedInputStream 和BufferedOutputStream,为IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式,提高了IO的性能
public static void copyFileBuffer(File srcFile,File destFile)throws IOException{if(!srcFile.exists())throw new IllegalArgumentException("原文件"+srcFile+"不存在");if(!srcFile.isFile())throw new IllegalArgumentException(srcFile+"不是文件");BufferedInputStream in = new BufferedInputStream(new FileInputStream(srcFile));BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(destFile));int n;while((n=in.read())!=-1){out.write(n);out.flush();//必须写}in.close();out.close();}
还可以自己写一个copyFileByByte(),经过比较,在进行较大的文件的copy工作时,自己创建byte[] 数组批量读取时,速度最快,带缓冲区的方式次之,当然可以想到,单个字节拷贝方式最慢。
字符流
1>认识文本和文本文件
java文本(char) 是16位无符号整数,是字符的Unicode编码(双字节编码)
文件是byte byte byte 。。 的序列集合文本文件是文本按照一定的编码方式序列化为byte的存储方式
2>字符流(Reader Writer)
字符流的底层仍然是基本的字节序列
字符流的基本实现 ---->操作文本文本文件
InputStreamReader -->完成byte流 解析为 char流 ,按照编码解析
OutputStreamWrite -->完成char流到byte流的解析,同样按照编码解析
public class FIRandFOW {public static void main(String[] args)throws IOException{FileInputStream in = new FileInputStream("C:\\unintall.log");/* * 可以指定编码方式,自动识别换行 */InputStreamReader reader = new InputStreamReader(in,"GBk");FileOutputStream out = new FileOutputStream("C:\\unintall1.log");OutputStreamWriter writer = new OutputStreamWriter(out,"GBk");int a;/* 单个字符读取while((a = reader.read())!=-1){System.out.print((char)a);}*///批量读取char[] buffer = new char[8*1024];while((a=reader.read(buffer,0,buffer.length))!=-1){writer.write(buffer, 0, a);writer.flush();//要加上刷新,才能及时将字符数组中的内容输出到文件String s = new String(buffer,0,a);System.out.println(s);}}}
FileReader 和 FileWriter
同 InputStreamReader 和 OutputStreamWriter读取字符和字符数组方式一样,只是创建对象的方式不同
DataInputStrean
FileReader read = new FileReader(file);
FileWriter write = new FileWriter(file); 构造函数的参数是File对象
注:这种字符流操作存在一些缺陷,我们看到在构造方法中没办法指定编码方式,所以,读取文件的编码必须和文件的编码相同,不然会出现乱码
字符流的过滤器
BufferedReader 和 BufferedWriter PrintWriter
优点是能以行为单位进行文件的读取
public class BufferReaderWriter{public static void main(String[] args) throws IOException{BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("C:\\unintall.log"),"GBK")); //BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\unintall1.log"))); PrintWriter pwriter = new PrintWriter("C:\\unintall1.log"); String line; /* while((line = reader.readLine()) != null) { writer.write(line);//不识别换行 writer.newLine();//手动换行 writer.flush(); System.out.println(line); }*/ /* * 由于BufferedWriter创建对象比较复杂,并且不识别换行,所以用PrintWriter替代 */ while((line = reader.readLine()) != null) { pwriter.println(line); //用该方法进行换行 pwriter.flush(); System.out.println(line); }}}
以上就是javaIO的基本类以及常用的操作,我们完全可以参照这篇文章对API中的其他IO类进行扩展学习
- Java专题之IO
- Java IO专题
- JAVA IO 专题
- Java小专题之IO
- IO 专题
- 【Java基础专题】IO与文件读写---Java的IO流架构
- Javo IO专题
- 专题3 标准IO编程
- Hadoop -【IO专题-序列化机制】
- io性能专题分析--持续跟新
- 【Java-IO】IO入门
- Java IO:IO框架
- 【IO】java IO 总结
- 专题:Java Servlets
- Java 代码质量专题
- IBM:Java 核心技术专题
- Java 核心技术专题
- Java EE 技术专题
- HDU 1032 The 3n + 1 problem(暴力)
- MySql 表管理常用的sql语句
- CString类
- 利用朴素贝叶斯算法实现垃圾邮件的过滤,并结合Adaboost改进该算法
- PHP引入文件的路径问题
- JAVA IO 专题
- NYOJ 117 求逆序数
- 剑指offer(七)之二进制中1的个数
- AngularJS ng-repeat下使用ng-model
- matlab 可视化 —— 常用绘图函数
- 我的个人博客上线了
- 基于Zookeeper的分步式队列系统集成案例
- 线性代数N阶行列式
- POI之Excel导出编码问题