本篇涉及到的流: 1.PrintWriter:字符打印输出流 2.PrintStream:字节打印输出流 3.SequenceInputStream :合并多个字节输入流 4.RandomAccessFile:随机操作文件 5.ObjectOutputStream与ObjectInputStream :对象的序列化流 6.DataInputStream与DataOutputStream :基本数据类型操作流 7.ByteArrayInputStream与ByteArrayOutputStream:字节数组操作流
无论是文件也好,字符串也好,字节输出流,字符输出流也好,总之一句话: 给我一个输出流,还你一个PrintWriter
想要将键盘录入保存到文件中,只要将控制台输出流换成文件输出流即可 其他部分同上
String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\PrintWriter.txt"; PrintWriter pw = new PrintWriter(new FileWriter(path), true); PrintWriter输出到文件.png无论是文件也好,字符串也好,字节输出流,总之一句话: 给我一个字节输出流,还你一个PrintStream
public class PrintWriterTest { public static void main(String[] args) { try { int a = Integer.parseInt("a"); } catch (NumberFormatException e) { e.printStackTrace(); } } } java.lang.NumberFormatException: For input string: "a" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.base/java.lang.Integer.parseInt(Integer.java:652) at java.base/java.lang.Integer.parseInt(Integer.java:770) at top.toly.IO.io.其他流.PrintWriterTest.main(PrintWriterTest.java:12)所有异常继承自:Throwable 类 其中有个不起眼的方法printStackTrace(),一般放着也没人管 但它有的重载的方法void printStackTrace(PrintStream s) 可以自定义输出流
public class PrintStreamTest { public static void main(String[] args) throws FileNotFoundException { try { int a = Integer.parseInt("a"); } catch (NumberFormatException e) { e.printStackTrace();//默认是输出到控制台:即System.out流 //将信息打印到F:\log.txt文件中 e.printStackTrace(new PrintStream("F:\\log.txt")); } } } 输出错误日志到文件.png也可以加入异常的时间
//将信息打印到F:\log.txt文件中 PrintStream ps = new PrintStream("F:\\log.txt"); ps.println(new SimpleDateFormat(" G yyyy/MM/dd 星期--EE a hh:mm:ss ").format(new Date().getTime())); e.printStackTrace(ps);//默认是输出到控制台:即System.out流当一个文件过大时,可以分割成多个小块 比如将一个1GB的电影分割成10份,每份100+M,由于字节不完整,导致无法播放 所以别人也不知道是什么电影 想看时用合并流合并一下,就能正常播放了。 可以搞个切合播放器,关闭播放器将电影切割,需要打开时碎片合并,然后就神不知鬼不觉。
目标文件Activity.md --7.34 KB (7,521 字节),按3KB大小切
public class SplitFile { public static void main(String[] args) throws Exception { String pathS = "I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity.md"; File fileS = new File(pathS); FileInputStream fis = new FileInputStream(pathS); //获取待切分文件名,以它作文文件夹,放入切分后的 File parent = new File(fileS.getParentFile().getAbsolutePath() + File.separator + fileS.getName().split("\\.")[0]); parent.mkdir(); int count = 0; int len = 0; byte[] buf = new byte[1024 * 3];//每份3kb,最后一份小于或等于3kb while ((len = fis.read(buf)) != -1) { File fileT = new File(parent, (count++) + ".temp"); FileOutputStream fos = new FileOutputStream(fileT); fos.write(buf, 0, len); fos.close(); } fis.close(); } } 切割文件.png合并
public class SISTest { public static void main(String[] args) throws Exception { FileInputStream fis1 = new FileInputStream("I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity\\0.temp"); FileInputStream fis2 = new FileInputStream("I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity\\1.temp"); FileInputStream fis3 = new FileInputStream("I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity\\2.temp"); //使用Vector获取Enumeration对象 ArrayList<InputStream> list = new ArrayList<>(); list.add(fis1); list.add(fis2); list.add(fis3); //基于ArrayList合并流:需自定义Enumeration final Iterator<InputStream> it = list.iterator(); Enumeration<InputStream> en = new Enumeration<>() { @Override public boolean hasMoreElements() { return it.hasNext(); } @Override public InputStream nextElement() { return it.next(); } }; SequenceInputStream sis = new SequenceInputStream(en);//合并输入流 //创建输出流 FileOutputStream fos = new FileOutputStream("I:\\Java\\Base\\Thinking\\src\\IOTest\\Activity\\Activity.md"); int len = 0; byte[] buf = new byte[1024]; while ((len = sis.read(buf)) != -1) { fos.write(buf, 0, len); } sis.close(); fos.close(); } }使用ObjectOutputStream将对象序列化成为数据输出-->将对象持久存储 使用ObjectInputStream进行读取序列化的数据-->恢复先前对象 只能序列化堆中的对象,static修饰的成员变量不能被序列化 transient修饰的成员变量,即使在堆内存中也不会被序列化
相当于给个文件给你,你直接读出来一个对象,创建,赋值什么的都已经搞定了 对于十分复杂的对象序列化还是很方便的,但由于是IO,相对比较耗时
private static void readObject() throws IOException, ClassNotFoundException { String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\ObjectOutputStream.txt"; ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path)); Person toly = (Person) ois.readObject(); System.out.println(toly);//Person{name='捷特', age=24}1.该类不是算是IO体系中子类。而是直接继承自Object。 2.但是它是IO包中成员。因为它具备读和写功能,内部封装字节输入流和输出流。 3.内部封装数组,通过指针对数组的元素进行操作,getFilePointer获取指针位置,通过seek改变指针的位置 4.只能操作磁盘文件,
可见38和527654两个int值以&字符展现出来,utf-8码表第38为是&这情有可原,527654怎么也来插一脚 众所周知,一个int占4个字节,一个字节是8位,也就是一个int占32位,转换成二进制即下面:
3366 0000 0000 0000 1000 0000 1101 0010 0110 38 0000 0000 0000 0000 0000 0000 0010 0110 RandomAccessFile写入时int只写入低8位(因为字符写入,一次只能写一个字节即8位),即0010 0110解决方法:将一个int分为4次来读,每次读一个字节(8位),写入文件
raf.writeInt(527654);//RandomAccessFile内部已经封装 RandomAccessFile2.pngByteArrayInputStream :在构造的时候,需要数据源:一个字节数组,缓冲区会随数据自动增长。 ByteArrayOutputStream: 在构造的时候,该对象中已经内部封装了可变长度的字节数组,是数据目的地。
public class BAIS_BAOS_Test { public static void main(String[] args) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream("张风捷特烈".getBytes()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); System.out.println(baos.size());//0 int by = 0; while ((by = bais.read()) != -1) { baos.write(by); } System.out.println(baos.size());//15 = 3 * 5 //写到控制台 baos.writeTo(System.out);//张风捷特烈 //写到文件 String path = "I:\\Java\\Base\\Thinking\\src\\IOTest\\ByteArrayOutputStream.txt"; baos.writeTo(new FileOutputStream(path)); } }其他几个操作类似,顺便提一下
类IO流类型操作数据ByteArrayInputStream输入流I字节流字节数组ByteArrayOutputStream输出流O字节流字节数组CharArrayReader输出流I字符流字符数组CharArrayWriter输出流O字符流字符数组StringReader输出流I字符流字符串StringWriter输出流O字符流字符串1----本文由张风捷特烈原创,转载请注明 2----欢迎广大编程爱好者共同交流 3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 4----看到这里,我在此感谢你的喜欢与支持
转载于:https://www.cnblogs.com/toly-top/p/9781847.html