java IO小结
package 字符与字节转换; import java.io.*; public class char_byte { public static void main(String[] args) { // TODO 自动生成的方法存根 } } //理解1 /*java是面向对象的,所有的输入输出都是对 对象而言 以下面的为例 :FileOutputStream fos1 = new FileOutputStream("D:/abc1.txt"); 对对象fos1来说文件是输出目标,而 FileInputStream fis2 = new FileInputStream("D:/abc2.txt");对象fis2的文件是输入来源。 */ //理解2 /* *输入流和输出流相对于内存设备而言:将外设中的数据读取到内存中:输入。 *将内存中的数据写出到外设中:输出。 *新生成的对象都是放在内存中的,上面的理解也大概是对的。 */ //理解3 /* 流按照操作数据分为两种:字节流和字符流。 字符流的由来:其实就是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,再对这个文字进行操作。简单来说:字节流+编码表。 /* //理解4 * 后缀名是父类名,前缀名是该流对象的功能。该对象可以直接操作的类型。read方法在提升,而write方法在降低。 * //理解5 * writer reader 的本质实现是加了buff缓冲的字节,下面是字节转字符。 * public void write(int c) throws IOException { synchronized (lock) { ensureOpen(); if (nextChar >= nChars) flushBuffer(); cb[nextChar++] = (char) c; } } FileOutputStream 三个主要的方法: void write(int b) 写入一个int数字对应的byte,这点很奇怪:write(65535)和write(255)得到的结果是一致的,write方法只写入int b的最后面8位(一个byte)。需要注意一下。 void write(byte[] b) 写入一个byte数组。因为是字节流,所以在想用这个方法写入字符串到文件的时候,传入的参数应该是调用String类的getBytes方法将字符串转成byte数组再传入。 void write(byte[] b, int off, int len) 写入一个byte数组的制定起始脚标的长度。这个在拷贝文件或者网络传输的时候会常用的,因为需要数出的数据通常不会正好被byte数组b的长度整除,而是有多余的,这里就需要只输出多余的字节。 FileInputStream int read() 从此输入流中读取一个数据字节。返回读到的byte的int形式,到文件末尾返回的是-1。 int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。返回的为读到的数组的长度。到文件末尾返回-1. int read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。返回的为读到的数组的长度。到文件末尾返回-1. */ class BinFileReadDemo { public static void test1() throws IOException { FileOutputStream fos1 = new FileOutputStream("D:/abc1.txt"); for (int x = 1; x < 512; x += 16) { fos1.write(x); } fos1.close(); FileOutputStream fos2 = new FileOutputStream("D:/abc2.txt"); fos2.write("我是一个字符串".getBytes()); fos2.close(); } public static void test2() throws IOException { FileInputStream fis1 = new FileInputStream("D:/abc1.txt"); int num1; while ((num1 = fis1.read()) != -1) { System.out.print(Integer.toHexString(num1) + " "); } fis1.close(); System.out.println(""); System.out.println("--------------------------------------------------"); FileInputStream fis2 = new FileInputStream("D:/abc2.txt"); int num2; byte[] b = new byte[1024]; num2 = fis2.read(b); System.out.write(b, 0, num2); fis2.close(); } //普通拷贝 public static void test3() throws IOException { FileInputStream fis = new FileInputStream("D:/abc1.mp3"); FileOutputStream fos = new FileOutputStream("D:/abc2.mp3"); byte[] b = new byte[1024 * 1024]; int len; while ((len = fis.read(b)) != -1) { fos.write(b, 0, len); } fis.close(); fos.close(); } //对于字节流,也有对应的增强类BufferedOutputStream和BufferedInputStream。 public static void test4() throws IOException { long start = System.currentTimeMillis(); BufferedInputStream buffis = new BufferedInputStream( new FileInputStream("D:/jdk-7u9-windows-x64.exe")); BufferedOutputStream buffos = new BufferedOutputStream( new FileOutputStream("D:/jdk-7u9-windows-x64-2.exe")); int num; while ((num = buffis.read()) != -1) { buffos.write(num); } buffis.close(); buffos.close(); long end = System.currentTimeMillis(); System.out.println((end - start) + "毫秒"); } //由用户输入字符串,代码将用户的键盘输入转成大写返回。 public static void test5() throws IOException { InputStream in = System.in; int b = 0; StringBuilder sb = new StringBuilder(); while (true) { b = in.read(); if ((char) b == '\r') continue; if ((char) b == '\n') { String str = sb.toString(); if ("over".equals(str)) break; System.out.println(str.toUpperCase()); sb.delete(0, sb.length()); } else sb.append((char) b); } in.close(); } //考虑到处理换行,可使用BufferedReader,而且键盘输入是字节流,还要考虑到字节流向字符流的转换 public static void test6() throws IOException { BufferedReader bufr = new BufferedReader(new InputStreamReader( System.in)); String line = null; while ((line = bufr.readLine()) != null) { if ("over".equals(line)) break; System.out.println(line.toUpperCase()); } bufr.close(); } //将键盘录入转成大写后输出到一个文件中 public static void test7() throws IOException { BufferedReader bufr = new BufferedReader(new InputStreamReader( System.in)); BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter( new FileOutputStream("d:/www.txt"))); String line = null; while ((line = bufr.readLine()) != null) { if ("over".equals(line)) break; bufw.write(line.toUpperCase()); bufw.newLine(); } bufr.close(); bufw.close(); } }
[code=java] import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import sun.nio.*; class hello{ public static void main(String[] args)throws IOException{ main1(); main2(); main3(); main4(); } static void main1() throws IOException{ File resouceFile = new File("E:\\test.txt"); File targetFile = new File("E:\\copyOftest1.txt"); BufferedReader br = new BufferedReader(new FileReader(resouceFile)); BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile)); String aString; //char[] cbuf = new char[1024]; //int n = 0; while((aString = br.readLine()) != null){ bw.write(aString); bw.newLine(); } //不要忘记刷新和关闭流、否则一方面资源没有及时释放、另一方面有可能照成数据丢失 br.close(); bw.flush(); bw.close(); } static void main2() throws IOException{ File resouceFile = new File("e:\\test.txt"); File targetFile = new File("E:\\copyOftest2.txt"); BufferedReader br = new BufferedReader(new FileReader(resouceFile)); BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile)); char[] cbuf = new char[1024]; int n = 0; while((n = br.read(cbuf)) != -1){ bw.write(cbuf, 0, n); } //不要忘记刷新和关闭流、否则一方面资源没有及时释放、另一方面有可能照成数据丢失 br.close(); bw.flush(); bw.close(); } static void main3() throws IOException{ //读取全部文件,但无法解析中文字符 RandomAccessFile testRFile=new RandomAccessFile("E:"+File.separator+"test.txt", "rw"); RandomAccessFile testWFile=new RandomAccessFile("E:"+File.separator+"test3.txt", "rw"); byte cc; try{ while ((cc=testRFile.readByte())!=-1) {//按字节来写,那就不用在乎编码了!!但很难打印出来看。 //System.out.println((char)cc); testWFile.write(cc); } }catch (Exception e) { // TODO: handle exception } //File aFile=new File("E:"+File.separator+"test3.txt"); //OutputStream aa=new FileOutputStream(aFile); //Writer out= new BufferedWriter(new OutputStreamWriter(aa)); //Writer out= new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("E:"+File.separator+"test3.txt")))); //输入字符串,缓存并以字节的形式保存文件 Writer out= new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:"+File.separator+"test3.txt"))); out.write("这是一个测试2"); out.flush(); out.close(); } //上面是按一个字节一个字节的读写,比较慢,下面是优化,按一个数组一个数组的读写! static void main4() throws IOException{ RandomAccessFile testRFile=new RandomAccessFile("E:"+File.separator+"test.txt", "rw"); RandomAccessFile testWFile=new RandomAccessFile("E:"+File.separator+"test4.txt", "rw"); int readsize=0; for (int i=0;i<=(testRFile.length()/1024+1);i++){ byte[] bb=new byte[1024]; readsize=testRFile.read(bb); System.out.println(readsize); //System.out.println(new String(bb)); try { testWFile.write(bb,0,readsize); } catch (Exception e) { // TODO: handle exception } //System.out.println(new String(bb,"utf8"));//解析中文字符,但由于是数组形式的,会导致多余的null数据,可以用read时返回的int //来知道读了多少字节,写入文件时,再写入缓存数组的相应长度,就能解决!完美! } testRFile.close(); testWFile.close(); } } /* * 泛型:泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。 * 类型通配符一般是使用 ? 代替具体的类型实参。注意了,此处是类型实参,而不是类型形参!且Box<?>在逻辑上是Box<Integer>、Box<Number>...等所有Box<具体类型实参>的父类。 * 类型通配符上限通过形如Box<? extends Number>形式定义,相对应的,类型通配符下限为Box<? super Number>形式 K —— 键,比如映射的键。 V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。 E —— 异常类。 T —— 泛型。 List<?> 是任何泛型 List 的父类型 */ class FanXing{ static void main1(){ ArrayList<String> qrrayList=new ArrayList<String>(); qrrayList.add("first1"); qrrayList.add("first2"); qrrayList.add("first3"); qrrayList.add("first4"); } } [/code]
[code=java] /* class FileChannelTest { RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw"); FileChannel channel = aFile.getChannel(); String newData = "New String to write to file..." + System.currentTimeMillis(); //如果设置的大小不够存放newData,会抛异常java.nio.BufferOverflowException ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(newData.getBytes()); buf.flip();//limit设置为当前的position,准备读取这个buffer //FileChannel.write()是在while循环中调用的。 //因为无法保证write()方法一次能向FileChannel写入多少字节 //因此需要重复调用write()方法,直到Buffer中已经没有尚未写入通道的字节 while(buf.hasRemaining()) { channel.write(buf); } channel.close(); /** * 还有如下方法 * channel.size()//该实例关联文件的大小 * channel.truncate() 截取文件,指定长度后的部分将被删除 * channel.force(true);//强制内存数据flush到硬盘 */ [/code]