import java.io.*; /* 字符流 Writer |-FileWriter */ class FileTest { public static void main(String[] args) throws IOException { //创建一个FileWriter对象,同时会在制定目录创建一个文件 FileWriter fw = new FileWriter("test.txt"); //将字符写到流中 fw.write("Test"); //刷新缓冲中的数据,存到目的地 //fw.flush(); /* 关闭流之前会刷新流 flush和close区别: flush刷新后流还可以继续使用,close关闭流 后不能使用 */ fw.close(); } } 实例二: import java.io.*; /* 文件异常处理 */ class IOExceptionTest { public static void main(String[] args) { FileWriter fw = null; try { fw = new FileWriter("Test.txt"); fw.write("Test"); } catch (IOException ie) { System.out.println(ie.toString()); } finally { try { if(fw != null) fw.close(); } catch (IOException ie) { System.out.println(ie.toString()); } } } }
import java.io.*; /* 文件读取 */ class FileReaderTest { public static void main(String[] args) throws IOException { read_2(); } //读取一个字符 public static void read_1() throws IOException { FileReader fr = new FileReader("FileReaderTest.java"); int ch = 0; while((ch = fr.read()) != -1) { System.out.print((char)ch); } fr.close(); } //读取到字符数组 public static void read_2() throws IOException { FileReader fr = new FileReader("FileReaderTest.java"); //定义一个字符数组 char[] chs = new char[1024]; int num = 0; while((num = fr.read(chs)) != -1) { System.out.print(new String(chs, 0 ,num)); } fr.close(); } }
import java.io.*; /* 文件拷贝实例 步骤: 1、创建一个字符数组 2、读取字符并写入 注意:通过缓冲区中的readLine方法读取,不包括换行符 */ class FileCopyTest { public static void main(String[] args) throws IOException { copy_3(); } //通过缓冲区复制文件 public static void copy_3() { BufferedReader bufr = null; BufferedWriter bufw = null; try { bufr = new BufferedReader(new FileReader("FileCopyTest.java")); bufw = new BufferedWriter(new FileWriter("copy_test.txt")); String str = null; while((str = bufr.readLine()) != null) { bufw.write(str); bufw.newLine(); bufw.flush(); } } catch (IOException ie) { throw new RuntimeException("文件读取失败!"); // ie.printStackTrace(); } finally { if (bufr != null) { try { bufr.close(); } catch (IOException ie) { throw new RuntimeException("写文件关闭失败!"); } } if (bufw != null) { try { bufw.close(); } catch (IOException ie) { throw new RuntimeException("读文件关闭失败!"); } } } } //读取一个字符数组 public static void copy_2() { FileWriter fw = null; FileReader fr = null; try { fw = new FileWriter("Copy_2_test.txt"); fr = new FileReader("FileCopyTest.java"); char[] buf = new char[1024]; int len = 0 ; while((len = fr.read(buf)) != -1) { fw.write(buf, 0, len); } } catch (IOException ie) { throw new RuntimeException("文件读取失败"); } finally { if (fw != null) { try { fw.close(); } catch (IOException ie) { } } if (fr != null) { try { fr.close(); } catch (IOException ie) { } } } } //读取一个字符就写入 public static void copy_1() throws IOException { FileWriter fw = new FileWriter("Copy_1_Test.txt"); FileReader fr = new FileReader("FileCopyTest.java"); int temp = 0; while((temp = fr.read()) != -1) { fw.write(temp); } fw.close(); fr.close(); } }
import java.io.*; /* 实现readLine 原理:就是一个一个的读取字符,在判断改字符如果不是换行符, 就存入缓冲区,如果是则返回缓冲区中的字符 */ //MyBufferedReader class MyBufferedReader { private FileReader fr; public MyBufferedReader(FileReader fr) { this.fr = fr; } //读取一行方法 public String myReadLine() throws IOException { //定义缓冲区 StringBuilder sb = new StringBuilder(); //读取字符 int ch = 0; while ((ch = fr.read()) != -1) { if(ch == '\r') continue; if(ch == '\n') return sb.toString(); else sb.append((char)ch); } if(sb.length() != 0) return sb.toString(); return null; } //关闭流 public void myColse() throws IOException { fr.close(); } } class MyReadLine { public static void main(String[] args) throws IOException { MyBufferedReader mybuf = new MyBufferedReader(new FileReader("test.txt")); String str = null; while((str = mybuf.myReadLine()) != null) { System.out.println(str); } } }
import java.io.*; /* 类 LineNumberReader int getLineNumber() 获得当前行号。 void setLineNumber(int lineNumber) 设置当前行号。 1、测试这两个方法 2、自定义类实现上述方法 */ class BufferedLineNumber { public static void main(String[] args) throws IOException { test_2(); } //2 public static void test_2() throws IOException { FileReader fr = new FileReader("BufferedLineNumber.java"); MyBufferedLineNumber mybufr = new MyBufferedLineNumber(fr); String str = null; mybufr.setLineNum(100); while((str = mybufr.readLine()) != null) { System.out.println(mybufr.getLineNum() + ":" + str); } } //1 public static void test_1() throws IOException { LineNumberReader lnbr = new LineNumberReader(new FileReader("BufferedLineNumber.java")); lnbr.setLineNumber(100); //101开始 String str = null; while((str = lnbr.readLine()) != null) { System.out.println(lnbr.getLineNumber() + ":" + str); } } } //自定义类,用来增强BufferedReader类 class MyBufferedLineNumber { public MyBufferedLineNumber(Reader r) { this.r = r; } public String readLine() throws IOException { i++; StringBuilder sb = new StringBuilder(); int str = 0; while((str = r.read()) != -1) { if(str == '\r') continue; if(str == '\n') return sb.toString(); sb.append((char)str); } if(sb.length() != 0) return sb.toString(); return null; } public void close() throws IOException { r.close(); } public int getLineNum() { return i; } public void setLineNum(int i) { this.i = i; } private Reader r; private int i; } 字符流常用对象: FileReader FileWriter BufferedReader BufferedWriter
----------------------------------
字节流
实例一; import java.io.*; /* 字节流测试 InputStream OutputStream 注意:字节流写时,不需要刷新 */ class StreamTest { public static void main(String[] args) throws IOException { outputTest(); } //一次性读取完 public static void test_3() throws IOException { FileInputStream fis = new FileInputStream("Test.txt"); int len = fis.available(); byte[] temp = new byte[len]; fis.read(temp); System.out.print(new String(temp)); fis.close(); } //读取一个字节数组 public static void test_2() throws IOException { FileInputStream fis = new FileInputStream("Test.txt"); byte[] temp = new byte[1024]; int len = 0; while((len = fis.read(temp)) != -1) { System.out.print(new String(temp)); } fis.close(); } //读取一个打印一个 public static void test_1() throws IOException { FileInputStream fis = new FileInputStream("Test.txt"); int len = 0; while((len = fis.read()) != -1) { System.out.print((char)len + " "); } fis.close(); } //输出 public static void outputTest() throws IOException { FileOutputStream fos = new FileOutputStream("Test.txt"); fos.write("这是字符串".getBytes()); fos.close(); } }
----------------------------------
字节流
实例一; import java.io.*; /* 字节流测试 InputStream OutputStream 注意:字节流写时,不需要刷新 */ class StreamTest { public static void main(String[] args) throws IOException { outputTest(); } //一次性读取完 public static void test_3() throws IOException { FileInputStream fis = new FileInputStream("Test.txt"); int len = fis.available(); byte[] temp = new byte[len]; fis.read(temp); System.out.print(new String(temp)); fis.close(); } //读取一个字节数组 public static void test_2() throws IOException { FileInputStream fis = new FileInputStream("Test.txt"); byte[] temp = new byte[1024]; int len = 0; while((len = fis.read(temp)) != -1) { System.out.print(new String(temp)); } fis.close(); } //读取一个打印一个 public static void test_1() throws IOException { FileInputStream fis = new FileInputStream("Test.txt"); int len = 0; while((len = fis.read()) != -1) { System.out.print((char)len + " "); } fis.close(); } //输出 public static void outputTest() throws IOException { FileOutputStream fos = new FileOutputStream("Test.txt"); fos.write("这是字符串".getBytes()); fos.close(); } }
import java.io.*; /* 字节流拷贝文件 1、将源文件与字节输入流相关联 2、将目标文件与字节输出流相关联 3、拷贝 */ class CopyPic { public static void main(String[] args) { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("c:\\1.bmp"); //源 fos = new FileOutputStream("c:\\2.bmp"); //目标 int len = 0; byte[] sub = new byte[1024]; while((len = fis.read(sub)) != -1) { fos.write(sub, 0, len); } } catch (IOException ie) { throw new RuntimeException("文件拷贝失败!"); } finally { if (fis != null) { try { fis.close(); } catch (IOException ie) { throw new RuntimeException("源文件关闭失败!"); } } if (fos != null) { try { fos.close(); } catch (IOException ie) { throw new RuntimeException("源文件关闭失败!"); } } } } }
import java.io.*; /* 拷贝mp3 */ class CopyMp3 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); copyTest(); long end = System.currentTimeMillis(); System.out.println((end - start) + "毫秒"); } public static void copyTest() throws IOException { BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\1.mp3")); //源文件 BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\2.mp3")); //目标文件 int len = 0; while((len = bufis.read()) != -1) { bufos.write(len); } bufis.close(); bufos.close(); } } 四、自定义InputStream缓冲区 import java.io.*; /* 实现BufferedInputStreame功能 步骤: 1、首先定义InputStremae变量用来接受传进来的对象 2、定义一字节数组和两个变量 */ class MyBufferedInputStream { private InputStream r; private int pos; private int count; private byte[] sub = new byte[1024]; MyBufferedInputStream(InputStream r) { this.r = r; } public int read() throws IOException { if (count == 0) //如果count等于0说明字节数组中的数据取完了 { count = r.read(sub); //取数据到缓冲区 if (count < 0) //说明文件已经读取完了 return -1; pos = 0; byte b = sub[pos]; count--; //计数器减一 pos++; //位置自增 return b & 0xff; } else if (count > 0) { byte b = sub[pos]; count--; pos++; return b & 0xff; } return -1; } //close public void close() throws IOException { r.close(); } }
import java.io.*; /* 从键盘读取数据 需求: 1、从键盘读取一串数据 敲回车后全部打印 2、如果输入over则停止输入 */ class ReadIn { public static void main(String[] args) throws IOException { test_2(); } //方式二 将InputStream流转成Reader流 public static void test_2() throws IOException{ // //获取键盘输入流 // InputStream in = System.in; // // //将字节流转换成字符流 // InputStreamReader is = new InputStreamReader(in); // // //为了提高读取效率使用缓冲技术 // BufferedReader bufi = new BufferedReader(is); //1、键盘录入 // BufferedReader bufi = new BufferedReader(new InputStreamReader(System.in)); //2、读取文件 BufferedReader bufi = new BufferedReader(new InputStreamReader(new FileInputStream("ReadIn.java"))); // //将输出字节流转缓存字节流 // OutputStream out = System.out; // OutputStreamWriter outw = new OutputStreamWriter(out); // BufferedWriter bufw = new BufferedWriter(outw); //1、输出到控制台 // BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out)); //2、输出到文件 BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt"))); String line = null; while((line = bufi.readLine()) != null) { if("over".equals(line)) break; bufw.write(line); bufw.newLine(); bufw.flush(); // System.out.println(line); } } //方式一 public static void test_1() throws IOException { InputStream in = System.in; StringBuilder sb = new StringBuilder(); int ch = 0; while(true) { ch = in.read(); if(ch == 13) continue; if(ch == 10) { if("over".equals(sb.toString())) break; System.out.println(sb.toString()); sb.delete(0, sb.length()); } else { sb.append((char)ch); } } } }
import java.io.*; /* 实现BufferedInputStreame功能 步骤: 1、首先定义InputStremae变量用来接受传进来的对象 2、定义一字节数组和两个变量 */ class MyBufferedInputStream { private InputStream r; private int pos; private int count; private byte[] sub = new byte[1024]; MyBufferedInputStream(InputStream r) { this.r = r; } public int read() throws IOException { if (count == 0) //如果count等于0说明字节数组中的数据取完了 { count = r.read(sub); //取数据到缓冲区 if (count < 0) //说明文件已经读取完了 return -1; pos = 0; byte b = sub[pos]; count--; //计数器减一 pos++; //位置自增 return b & 0xff; } else if (count > 0) { byte b = sub[pos]; count--; pos++; return b & 0xff; } return -1; } //close public void close() throws IOException { r.close(); } }
import java.io.*; /* File类 列出目录中的目录 */ class FileTest { public static void main(String[] args) { File f = new File("c:/testdir"); removeDir(f); } //输出目录前面的空格 public static String getLevel(int n) { StringBuilder sb = new StringBuilder(); sb.append("|--"); for(int i=0;i<n;i++) { sb.insert(0, " "); } return sb.toString(); } //递归删除一个目录 public static void removeDir(File dir) { File[] files = dir.listFiles(); for(File f : files) { if(f.isDirectory()) { removeDir(f); } else { out(f + "--file--" + f.delete()); } } out(dir + "--dir--" + dir.delete()); } //列出目录和文件1 public static void showDir(File dir, int level) { // out(getLevel(level) + dir.getPath()); level++; File[] files = dir.listFiles(); for(File f : files) { if(f.isDirectory()) { showDir(f, level); } else { out(getLevel(level) + f.getName()); } } } //输出 public static void out(Object obj) { System.out.println(obj); } }
import java.io.*; class PrintStreamDemo { public static void main(String[] args) throws IOException { BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true); String line = null; while((line=bufr.readLine())!=null) { if("over".equals(line)) break; out.println(line.toUpperCase()); //out.flush(); } out.close(); bufr.close(); } }
import java.io.*; import java.util.*; class SplitFile { public static void main(String[] args) throws IOException { //splitFile(); merge(); } public static void merge()throws IOException { ArrayList<FileInputStream> al = new ArrayList<FileInputStream>(); for(int x=1; x<=3; x++) { al.add(new FileInputStream("c:\\splitfiles\\"+x+".part")); } final Iterator<FileInputStream> it = al.iterator(); Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() { public boolean hasMoreElements() { return it.hasNext(); } public FileInputStream nextElement() { return it.next(); } }; SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp"); byte[] buf = new byte[1024]; int len = 0; while((len=sis.read(buf))!=-1) { fos.write(buf,0,len); } fos.close(); sis.close(); } public static void splitFile()throws IOException { FileInputStream fis = new FileInputStream("c:\\1.bmp"); FileOutputStream fos = null; byte[] buf = new byte[1024*1024]; int len = 0; int count = 1; while((len=fis.read(buf))!=-1) { fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part"); fos.write(buf,0,len); fos.close(); } fis.close(); } }
import java.io.*; import java.util.*; class SequenceDemo { public static void main(String[] args) throws IOException { Vector<FileInputStream> v = new Vector<FileInputStream>(); v.add(new FileInputStream("c:\\1.txt")); v.add(new FileInputStream("c:\\2.txt")); v.add(new FileInputStream("c:\\3.txt")); Enumeration<FileInputStream> en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("c:\\4.txt"); byte[] buf = new byte[1024]; int len =0; while((len=sis.read(buf))!=-1) { fos.write(buf,0,len); } fos.close(); sis.close(); } }
IO包中其他流
1、将Person对象写到文件
Person:
import java.io.*; class Person implements Serializable { public static final long serialVersionUID = 42L; private String name; transient int age; static String country = "cn"; Person(String name,int age,String country) { this.name = name; this.age = age; this.country = country; } public String toString() { return name+":"+age+":"+country; } }
ObjectStreamDemo:
import java.io.*; class ObjectStreamDemo { public static void main(String[] args) throws Exception { //writeObj(); readObj(); } public static void readObj()throws Exception { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt")); Person p = (Person)ois.readObject(); System.out.println(p); ois.close(); } public static void writeObj()throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt")); oos.writeObject(new Person("lisi0",399,"kr")); oos.close(); } }
import java.io.*; class Read implements Runnable { private PipedInputStream in; Read(PipedInputStream in) { this.in = in; } public void run() { try { byte[] buf = new byte[1024]; System.out.println("读取前。。没有数据阻塞"); int len = in.read(buf); System.out.println("读到数据。。阻塞结束"); String s= new String(buf,0,len); System.out.println(s); in.close(); } catch (IOException e) { throw new RuntimeException("管道读取流失败"); } } } class Write implements Runnable { private PipedOutputStream out; Write(PipedOutputStream out) { this.out = out; } public void run() { try { System.out.println("开始写入数据,等待6秒后。"); Thread.sleep(6000); out.write("piped lai la".getBytes()); out.close(); } catch (Exception e) { throw new RuntimeException("管道输出流失败"); } } } class PipedStreamDemo { public static void main(String[] args) throws IOException { PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(); in.connect(out); Read r = new Read(in); Write w = new Write(out); new Thread(r).start(); new Thread(w).start(); } }
import java.io.*; /* RandomAccessFile 该类不是算是IO体系中子类。 而是直接继承自Object。 但是它是IO包中成员。因为它具备读和写功能。 内部封装了一个数组,而且通过指针对数组的元素进行操作。 可以通过getFilePointer获取指针位置, 同时可以通过seek改变指针的位置。 其实完成读写的原理就是内部封装了字节输入流和输出流。 通过构造函数可以看出,该类只能操作文件。 而且操作文件还有模式:只读r,,读写rw等。 如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。 如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。 */ class RandomAccessFileDemo { public static void main(String[] args) throws IOException { //writeFile_2(); //readFile(); //System.out.println(Integer.toBinaryString(258)); } public static void readFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","r"); //调整对象中指针。 //raf.seek(8*1); //跳过指定的字节数 raf.skipBytes(8); byte[] buf = new byte[4]; raf.read(buf); String name = new String(buf); int age = raf.readInt(); System.out.println("name="+name); System.out.println("age="+age); raf.close(); } public static void writeFile_2()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","rw"); raf.seek(8*0); raf.write("周期".getBytes()); raf.writeInt(103); raf.close(); } public static void writeFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","rw"); raf.write("李四".getBytes()); raf.writeInt(97); raf.write("王五".getBytes()); raf.writeInt(99); raf.close(); } }
DataInputStream和DataOutputStream
/* DataInputStream与DataOutputStream 可以用于操作基本数据类型的数据的流对象。 */ import java.io.*; class DataStreamDemo { public static void main(String[] args) throws IOException { //writeData(); //readData(); //writeUTFDemo(); // OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk"); // // osw.write("你好"); // osw.close(); // readUTFDemo(); } public static void readUTFDemo()throws IOException { DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt")); String s = dis.readUTF(); System.out.println(s); dis.close(); } public static void writeUTFDemo()throws IOException { DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt")); dos.writeUTF("你好"); dos.close(); } public static void readData()throws IOException { DataInputStream dis = new DataInputStream(new FileInputStream("data.txt")); int num = dis.readInt(); boolean b = dis.readBoolean(); double d = dis.readDouble(); System.out.println("num="+num); System.out.println("b="+b); System.out.println("d="+d); dis.close(); } public static void writeData()throws IOException { DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt")); dos.writeInt(234); dos.writeBoolean(true); dos.writeDouble(9887.543); dos.close(); ObjectOutputStream oos = null; oos.writeObject(new O()); } }
ByteArrayInputStream和ByteArrayOutputStream
/* 用于操作字节数组的流对象。 ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。 ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。 这就是数据目的地。 因为这两个流对象都操作的数组,并没有使用系统资源。 所以,不用进行close关闭。 在流操作规律讲解时: 源设备, 键盘 System.in,硬盘 FileStream,内存 ArrayStream。 目的设备: 控制台 System.out,硬盘FileStream,内存 ArrayStream。 用流的读写思想来操作数据。 */ import java.io.*; class ByteArrayStream { public static void main(String[] args) { //数据源。 ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes()); //数据目的 ByteArrayOutputStream bos = new ByteArrayOutputStream(); int by = 0; while((by=bis.read())!=-1) { bos.write(by); } System.out.println(bos.size()); System.out.println(bos.toString()); // bos.writeTo(new FileOutputStream("a.txt")); } }
InputStreamReader和OutputStreamWriter
注意:中文GBK两个八位,最高位为1,也就是两个负数
编码实例1:
/* 编码:字符串变成字节数组。 解码:字节数组变成字符串。 String-->byte[]; str.getBytes(charsetName); byte[] -->String: new String(byte[],charsetName); */ import java.util.*; class EncodeDemo { public static void main(String[] args)throws Exception { String s = "哈哈"; byte[] b1 = s.getBytes("GBK"); System.out.println(Arrays.toString(b1)); String s1 = new String(b1,"utf-8"); System.out.println("s1="+s1); //对s1进行iso8859-1编码。 byte[] b2 = s1.getBytes("utf-8"); System.out.println(Arrays.toString(b2)); String s2 = new String(b2,"gbk"); System.out.println("s2="+s2); } }
这是因为将联通两个字编码后正好符合UTF-8读取规则,所以记事本将该文件识别成UTF-8格式,但是其实这个文件是GBK的,所以最后导致乱码
补充:UTF-8读取规则(在API,DataInputStream接口中,readUTF方法中)
开头为0,一个八位
开头为110,两个八位
开头为1110,三个八位
class EncodeDemo2 { public static void main(String[] args) throws Exception { String s = "联通ͨ"; byte[] by = s.getBytes("gbk"); for(byte b : by) { System.out.println(Integer.toBinaryString(b&255)); } System.out.println("Hello World!"); } }
import java.io.*; class EncodeStream { public static void main(String[] args) throws IOException { //writeText(); readText(); } public static void readText()throws IOException { InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"gbk"); char[] buf = new char[10]; int len = isr.read(buf); String str = new String(buf,0,len); System.out.println(str); isr.close(); } public static void writeText()throws IOException { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8"); osw.write("你好"); osw.close(); } }