黑马程序员——Java基础——IO输入与输出_3
来源:互联网 发布:黑暗骑士 知乎 编辑:程序博客网 时间:2024/03/29 10:00
IO流
作用:
利用Java语言中的IO流技术处理设备上的数据(硬盘上的文件,内存中驻留的数据)
分类:
按流向
- - - - 输入流
- - - - 输出流
按数据
- - - - 字节流
- - - - 字符流
抽象基类:
字符流
- - - - Reader
- - - - Writer
字节流
- - - - InputStream
- - - - OutputStream
功能性流对象
打印流
该流提供了打印方法,可以将各种数据类型的数据原样打印
字节打印流 PrintStream:
构造函数可以接收
- - - - File对象 File
- - - - 字符串路径 String
- - - - 字节输出流 OutputStream
字符打印流 PrintWriter:
构造函数可以接收
- - - - File对象 File
- - - - 字符串路径 String
- - - - 字节输出流 OutputStream
- - - - 字符输出流 Writer
public class PrintStreamDemo { public static void main(String[] args) throws IOException{ BufferedReader bufr = new BufferedReader( new InputStreamReader( System.in)); //基础形式 //PrintWriter out = new PrintWriter(System.out); //true参数表示如果是流,在输入回车后自动flush PrintWriter out = new PrintWriter(System.out, true); //输出到文件中,但是没有true参数,true参数配合流使用 //PrintWriter out = new PrintWriter("a.txt"); //将文件封装到流中,就可以配合true参数使用 //true参数只针对于流使用,PrintWriter(“a.txt”, true)非法 //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.close(); bufr.close(); }}
序列流
将多个流合并成一个流 SequenceInputStream
public class SequenceInputStreamDemo { public static void main(String[] args) throws IOException{ Vector<FileInputStream> v = new Vector<FileInputStream>(); v.add(new FileInputStream("d:\\test\\1.txt")); v.add(new FileInputStream("d:\\test\\2.txt")); v.add(new FileInputStream("d:\\test\\3.txt")); Enumeration<FileInputStream> en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("d:\\test\\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(); }}
文件切割
public class SplitFile { public static void main(String[] args) throws IOException{ splitFile(); merge(); } public static void merge() throws IOException{ ArrayList<FileInputStream> al = new ArrayList<FileInputStream>(); al.add(new FileInputStream("d:\\test\\1.part")); al.add(new FileInputStream("d:\\test\\2.part")); al.add(new FileInputStream("d:\\test\\3.part")); al.add(new FileInputStream("d:\\test\\4.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("d:\\test\\splitFile.mp3"); byte[] buf = new byte[1024 * 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("d:\\test\\sq.mp3"); FileOutputStream fos = null; byte[] buf = new byte[1024*1024]; int len = 0; int count = 1; while((len = fis.read(buf)) != -1){ fos = new FileOutputStream("d:\\test\\" + (count++) + ".part"); fos.write(buf, 0, len); fos.close(); } fis.close(); }}
对象的序列化
直接操作对象的流,将堆内存中的对象通过此类存入硬盘中(对象的持久化)
被操作对象需要实现Serializable接口(标记接口)
ObjectInputStream
ObjectOutputStream
当被序列化类被修改时,Java自动生成的UID改变,以序列化的该类对象是无法使用该类的,需自定义静态值serialVersionUID
静态变量是不能被序列化的
如果非静态的变量也不想被序列化则定义transient关键字
public class Person implements Serializable{ //自定义UID值,在类被修改时保证在未被修改之前生成类的对象也能够使用该类 private static final long serialVersionUID = 100L; private int id; private String name; //添加transient关键字,使非静态的参数不被序列化 transient int age; //静态变量不会被序列化 static String country = "cn"; Person(int id, String name, int age, String country){ this.id = id; this.name = name; this.age = age; this.country = country; } public String toString(){ return id + "::" + name + "::" + age + "::" + country; }}public class TestObjectStream { public static void main(String[] args) throws Exception{ writeObj(); readObj(); } public static void readObj() throws Exception{ ObjectInputStream ois = new ObjectInputStream( new FileInputStream("d:\\test\\Person.object")); Person p = (Person)ois.readObject(); System.out.println(p); ois.close(); } public static void writeObj()throws IOException{ ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("d:\\test\\Person.object")); oos.writeObject(new Person(001, "zhangsan", 27, "US")); oos.close(); }}
**输出结果为:**1::zhangsan::0::cn
管道流
输入输出可以直接进行连接,通过结合线程使用
PipedInputStream
PipedOutputStream
public 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(); }}class Read implements Runnable{ private PipedInputStream in; Read(PipedInputStream in){ this.in = in; } public void run() { try{ byte[] buf = new byte[1024]; int len = in.read(buf); 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{ out.write("PipedStream is coming~".getBytes()); out.close(); }catch(Exception e){ throw new RuntimeException("管道输出流失败~"); } }}
RandomAccessFile
该类配合多线程可以实现数据的分段写入
该类不算IO体系中的子类,直接继承Object类
但是是IO包中的成员,可以通过指针对数据的元素进行操作,可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置,完成读写的原理就是内部封装了字节数入流和输出流
该类只能操作文件,且该操作文件还有模式:只读“r”、读写“rw”等
public class RandomAccessFileDemo { public static void main(String[] args) throws IOException{ writeFile(); writeFile2(); readFile(); } public static void readFile() throws IOException{ RandomAccessFile raf = new RandomAccessFile("d:\\test\\4.txt", "r"); //指针索引指向第八位 raf.seek(8); //指针索引向右移动八位 raf.skipBytes(8); byte[] buf = new byte[4]; raf.read(buf); String s = new String(buf); int age = raf.readInt(); System.out.println("name:" + s); System.out.println("age:" + age); raf.close(); } public static void writeFile2() throws IOException{ RandomAccessFile raf = new RandomAccessFile("d:\\test\\4.txt", "rw"); //指针索引向右移动八位三次 raf.seek(8*3); //此时指针在第四个八位,写入数据 raf.write("周七".getBytes()); raf.writeInt(103); raf.close(); } public static void writeFile() throws IOException{ RandomAccessFile raf = new RandomAccessFile("d:\\test\\4.txt", "rw"); raf.write("张三".getBytes()); //写入一个数值用四个字节保存 raf.writeInt(97); }}
操作基本数据类型的流对象DataStream
DataInputStream
DataOutputStream
public class DataStreamDemo { public static void main(String[] args) throws IOException{ writeData(); readData(); writeUTF(); //自定义编码类型写入数据 OutputStreamWriter ows = new OutputStreamWriter( new FileOutputStream("d:\\test\\utf.txt"), "utf-8"); ows.write("你好"); ows.close(); readUTF(); } public static void readUTF() throws IOException{ DataInputStream dis = new DataInputStream( new FileInputStream("d:\\test\\utfData.txt")); String str = dis.readUTF(); System.out.println(str); } public static void writeUTF() throws IOException{ DataOutputStream dos = new DataOutputStream( new FileOutputStream("d:\\test\\utfData.txt")); dos.writeUTF("你好"); dos.close(); } public static void readData() throws IOException{ DataInputStream dis = new DataInputStream( new FileInputStream("d:\\test\\data.txt")); int i = dis.readInt(); boolean b = dis.readBoolean(); double d = dis.readDouble(); System.out.println(i + "::" + b + "::" + d); dis.close(); } public static void writeData() throws IOException{ DataOutputStream dos = new DataOutputStream( new FileOutputStream("d:\\test\\data.txt")); dos.writeInt(123); dos.writeBoolean(true); dos.writeDouble(241.231); dos.close(); }}
用于操作字节数组的流对象ByteArrayStream
在构造的时候需要接收一个数据源,且数据源是一个字节数组
ByteArrayOutputStream在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组
这两个流对象都操作的数组,并没有使用系统资源,所以不用进行close关闭
public class TestByteArrayDemo{ public static void main(String[] args) throws IOException{ ByteArrayInputStream bis = new ByteArrayInputStream("abcdefg".getBytes()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int ch = 0; while((ch = bis.read()) != -1){ bos.write(ch); } System.out.println(bos.size()); System.out.println(bos.toString()); //只有writeTO方法需要抛出异常 bos.writeTo(new FileOutputStream("d:\\test\\byteArrayDemo.txt")); }}
转换流的字符编码、字符编码、字符编码-联通
编码:字符串转换成字节数组
解码:字节数组转换成字符串
public class TransCharactorTest { public static void main(String[] args) throws IOException{ String s = "你好"; //用GBK进行编码 byte[] b1 = s.getBytes("GBK"); //数组转换成字符串 //System.out.println(Arrays.toString(b1)); String s1 = new String(b1, "ISO8859-1"); //用错误的解码格式进行编码,再用正确的格式进行解码 String s2 = new String(s1.getBytes("iso8859-1"), "GBK"); System.out.println("s2::" + s2); }}
练习
需求
有五个学生,每个学生有三门课程
从键盘输入以上数据(姓名,课程1, 2, 3)
计算出中成绩并把学生的信息和计算出的分数有高到低存放在文件“stud.txt”中
public class Test { public static void main(String[] args) throws IOException{ Comparator<Student> cmp = Collections.reverseOrder(); Set<Student> set = StudentInfoTool.getStudents(cmp); StudentInfoTool.writeToFile(set); }}class StudentInfoTool{ public static Set<Student> getStudents() throws IOException{ return getStudents(null); } public static Set<Student> getStudents(Comparator<Student> cmp) throws IOException{ BufferedReader bufr = new BufferedReader( new InputStreamReader(System.in)); String line = null; Set<Student> stus = null; if(cmp == null) stus = new TreeSet<Student>(); else stus = new TreeSet<Student>(cmp); while((line = bufr.readLine()) != null){ if("over".equals(line)) break; String[] info = line.split(","); Student stu = new Student(info[0], Integer.parseInt(info[1]), Integer.parseInt(info[2]), Integer.parseInt(info[3])); stus.add(stu); } bufr.close(); return stus; } public static void writeToFile(Set<Student> stus) throws IOException{ BufferedWriter bufw = new BufferedWriter( new FileWriter("d:\\test\\stud.txt")); for(Student stu: stus){ bufw.write(stu.toString() + "\t"); bufw.write(stu.getSum() + ""); bufw.newLine(); bufw.flush(); } bufw.close(); }}class Student implements Comparable<Student>{ private String name; private int ch, ma, en; private int sum; Student(String name, int ch, int ma, int en){ this.name = name; this.ch = ch; this.ma = ma; this.en = en; sum = ch + ma + en; } public String getName(){ return name; } public int getSum(){ return sum; } public int hashCode(){ return name.hashCode() + sum * 78; } public boolean equals(Object obj){ if(!(obj instanceof Student)){ throw new ClassCastException("类型不匹配"); } Student s = (Student)obj; return this.name.equals(s.name) && this.sum == sum; } public String toString(){ return "student[" + name + "," + ch + "," + ma + "," + en +"]"; } return int compareTo(Student s) { int num = new Integer(this.sum).compareTo(new Integer(s.sum)); if(num == 0) return this.name.compareTo(s.name); return num; }}
- 黑马程序员——Java基础——IO输入与输出_3
- 黑马程序员——java IO输入与输出
- 黑马程序员——Java基础——IO输入与输出_1
- 黑马程序员——Java基础——IO输入与输出_2
- 黑马程序员——IO输入与输出
- 黑马程序员——IO输入与输出(一)
- 黑马程序员——IO输入与输出(二)
- 黑马程序员——IO输入与输出
- 黑马程序员—IO输入与输出笔记
- 黑马程序员--Java基础--06输入与输出流IO
- 黑马程序员——JavaSE基础_3
- 黑马程序员——Java学习笔记之⑤——“IO输入与输出”
- 黑马程序员--java IO输入与输出
- 黑马程序员——Java基础---IO
- 黑马程序员——java基础--IO
- 黑马程序员——Java基础---IO
- 黑马程序员 Java基础——IO
- 黑马程序员—Java基础—IO
- PATBasic——1004. 成绩排名 (20)
- Windows7集成SP1微软原版光盘镜像下载大全
- 第16周项目1异常处理求平方根
- 搜狗语音云开发入门--移动端轻松添加高大上的语音识别
- 织梦后台文章发布时间为1970
- 黑马程序员——Java基础——IO输入与输出_3
- 关于职业发展
- 唐巧的iOS技术博客好文列表
- Theano2.1.13-基础知识之PyCUDA、CUDAMat、Gnumpy的兼容
- OOAD练习题
- 数据库事物隔离机制
- Mybaits的映射器配置详解
- 【leetcode c++】21 Merge Two Sorted Lists
- 迷你mysql操作类