zoukankan      html  css  js  c++  java
  • Java语言基础IO流(输入输出流) 其他

    Properties集合

    Map
        |--Hashtable
            |--Properties

    public class Properties extends Hashtable<Object,Object>
    Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
    Properties集合:
    特点:
    1.该集合中的键和值都是字符串类型;
    2.集合中的数据可以保存到流中或者从流中获取数据;

    应用场景:通常该集合用于操作以键值对存在的配置文件。

    package cn.itcase.io.p2.properties;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.Set;
    
    public class PropertiesDemo {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            // propertiesDemo();
            // propertiesDemo_2();
            // propertiesDemo_3();
            // propertiesDemo_4();
            // myLoad();
            test();
        }
    
        // 对已有的配置文件中的信息进行修改
        /*
         * 读取文件,并将这个文件中的键值数据存储到集合中;
         * 再通过集合对数据进行修改;
         * 再通过流将修改后的数据存储到文件中。
         */
        public static void test() throws IOException {
            // 读取这个文件
            File file = new File("info.txt");
    
            if (!file.exists()) {
                file.createNewFile();
            }
            FileReader fr = new FileReader("info.txt");
            
            // 如果放在这里,就新创建了文件覆盖掉原先的文件,文件为空
            // FileWriter fw=new FileWriter(file);
            // 创建集合,存储配置信息
            Properties prop = new Properties();
    
            // 将流中的信息存储到集合中
            prop.load(fr);
    
            prop.setProperty("wangwu", "16");
            FileWriter fw = new FileWriter(file);
            prop.store(fw, "");
    
            prop.list(System.out);
            fr.close();
        }
    
        /**
         * 模拟load方法
         * 
         * @throws IOException
         */
        public static void myLoad() throws IOException {
            Properties prop = new Properties();
    
            BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
    
            String line = null;
            while ((line = bufr.readLine()) != null) {
                if (line.startsWith("#"))
                    continue;
                String[] arr = line.split("=");
                // System.out.println(arr[0] + "::" + arr[1]);
                prop.setProperty(arr[0], arr[1]);
            }
            prop.list(System.out);
            bufr.close();
        }
    
        public static void propertiesDemo_4() throws IOException {
            Properties prop = new Properties();
    
            // 集合中的数据来自于一个文件
            // 注意:必须要保证该文件中的数据时键值对
            // 需要使用到读取流。
            FileInputStream fis = new FileInputStream("info.txt");
    
            // 使用load方法
            prop.load(fis);
            prop.list(System.out);
    
        }
    
        /**
         * 将字符串键值持久化存储到文件中
         * 
         * @throws IOException
         */
        public static void propertiesDemo_3() throws IOException {
            // 创建一个Properties集合
            Properties prop = new Properties();
    
            // 存储元素
            prop.setProperty("zhangsan", "30");
            prop.setProperty("lisi", "31");
            prop.setProperty("wangwu", "36");
            prop.setProperty("zhaoliu", "20");
    
            // 将这些集合中的字符串键值信息持久化存储到文件中
            // 需要关联输出流
            FileOutputStream fos = new FileOutputStream("info.txt");
    
            // 将集合中数据存储到文件中,使用store方法
            prop.store(fos, "info");
        }
    
        /**
         * 演示Properties集合与流对象相结合的功能
         */
        public static void propertiesDemo_2() {
            // 创建一个Properties集合
            Properties prop = new Properties();
    
            // 存储元素
            prop.setProperty("zhangsan", "30");
            prop.setProperty("lisi", "31");
            prop.setProperty("wangwu", "36");
            prop.setProperty("zhaoliu", "20");
    
            prop.list(System.out);// 将键和值打印到控制台
    
            // prop = System.getProperties();//获取系统信息
            // System.out.println(prop);
        }
    
        /*
         * Properties集合的存和取
         */
        public static void propertiesDemo() {
            // 创建一个Properties集合
            Properties prop = new Properties();
    
            // 存储元素
            prop.setProperty("zhangsan", "30");
            prop.setProperty("lisi", "31");
            prop.setProperty("wangwu", "36");
            prop.setProperty("zhaoliu", "20");
    
            // 修改元素
            prop.setProperty("wangwu", "26");
    
            // 取出所有元素
            Set<String> names = prop.stringPropertyNames();
            for (String name : names) {
                String value = prop.getProperty(name);
                System.out.println(name + ":" + value);
            }
        }
    
    }
    


    Properties集合应用示例:

    package cn.itcase.io.p2.properties;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    /*
     * 定义功能:获取一个应用程序运行的次数,如果超过5次,
     * 给出使用次数已到请注册的提示,并不再运行程序
     * 
     * 思路:
     * 1.需要计数器
     * 每次程序启动计数器需要计数一次,并且是在原有的次数上进行计数;
     * 2.计数器就是一个变量
     * 程序启动时,进行计数,计数器必须存在于内存中并进行运算;
     * 程序结束时,计数器会消失。那么再次启动该程序,计数器就重新被初始化。
     * 需要多次启动同一个应用程序,使用的是同一个计数器。
     * 这就需要计数器的生命周期编程,从内存存储到硬盘文件中。
     * 3.如何使用计数器?
     * 首先,程序启动时,应先读取这个用于记录计数器信息的配置文件,
     * 获取上一次计数次数,并进行试用次数的判断。
     * 其次,对该次数进行自增,并将自增后的次数重新存储到配置文件中。
     * 4.文件中信息的存储和体现
     * 使用键值对。
     * 可以使用有映射关系的map类集合,所以map+io=Properties
     */
    
    public class PropertiesTest {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            getAppCount();
        }
    
        public static void getAppCount() throws IOException {
            // 将所需的配置文件封装成File对象
            File confile = new File("count.properties");
    
            if (!confile.exists()) {
                confile.createNewFile();
            }
            FileInputStream fis = new FileInputStream(confile);
    
            Properties prop = new Properties();
            prop.load(fis);
    
            // 从集合中通过键获取次数
            String value = prop.getProperty("time");
    
            // 定义计数器,记录获取到的次数
            int count = 0;
            if (value != null) {
                count = Integer.parseInt(value);
                if (count >= 5) {
                    // System.out.println("使用次数已到,请注册!");
                    // return;
                    throw new RuntimeException("使用次数已到,请注册!");
                }
            }
            count++;
    
            // 将改变后的次数重新存储到集合中
            prop.setProperty("time", count + "");
    
            FileOutputStream fos = new FileOutputStream(confile);
            prop.store(fos, "");
    
            fos.close();
            fis.close();
    
        }
    }
    



    文件清单列表

    package cn.itcase.io.p3.test;
    
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.FilenameFilter;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    /*
     * 获取指定目录下,指定扩展名的文件(包含子目录中的)
     * 这些文件的绝对路径写入到一个文本文件中
     * 
     * 简单说,就是一个指定扩展名的文件列表
     * 
     * 思路:
     * 1.必须继承深度遍历;
     * 2.要在遍历的过程中进行过滤,将符合条件的内容都存储到容器中;
     * 3.对容器中的内容进行遍历,并将内容写入到文件中。
     */
    public class Test {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
    
            //创建File对象
            File dir=new File("e:\\PalInn");
            
            //实现过滤器
            FilenameFilter filter=new FilenameFilter(){
    
                @Override
                public boolean accept(File dir, String name) {
                    return name.endsWith(".exe");
                }
                
            };
            
            //创建暂存文件列表的list
            List<File> list=new ArrayList<File>();
            
            //遍历文件
            getFiles (dir,filter,list);
            
            //创建要存储信息的目标文件
            File destFile=new File(dir,"exelist.txt");
            
            //将list中存储的信息写入到目标文件中
            write2File(list, destFile);
        }
    
        /**
         * 对指定目录中的内容进行深度遍历,并按照指定过滤器,进行过滤
         * 
         * @param dir 要遍历的目录
         * @param filter 过滤器
         * @param list 暂存信息的容器
         */
        public static void getFiles(File dir, FilenameFilter filter, List<File> list) {
            File[] files = dir.listFiles();
    
            for (File file : files) {
                if (file.isDirectory()) {
                    // 递归
                    getFiles(file, filter, list);
                } else {
                    // 对遍历到的文件进行过滤,将符合条件的file对象存储到list集合中
                    if (filter.accept(file, file.getName())) {
                        list.add(file);
                    }
                }
            }
        }
    
        public static void write2File(List<File> list, File destFile) {
    
            BufferedWriter bufw = null;
    
            try {
                bufw = new BufferedWriter(new FileWriter(destFile));
                for(File file:list){
                    bufw.write(file.getAbsolutePath());
                    bufw.newLine();
                    bufw.flush();
                }
            } catch (IOException e) {
                throw new RuntimeException("写入失败!");
            } finally {
                if (bufw != null)
                    try {
                        bufw.close();
                    } catch (IOException e) {
                        throw new RuntimeException("关闭失败!");
                    }
            }
        }
    
    }
    


    打印流-PrintStream
    public class PrintStream extends FilterOutputStream implementsAppendable, CloseablePrintStream
    为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
    PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。

    package cn.itcase.io.p4.print.demo;
    
    import java.io.IOException;
    import java.io.PrintStream;
    
    public class PrintDemo {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            /*
             * PrintStream
             * 1.提供了打印的方法,可以对多种数据类型值进行打印,并保持数据的表示形式;
             * 2.它不抛出异常(IOException);
             * 
             * 构造函数接收三种类型的值:
             * 1.字符串路径;
             * 2.File对象;
             * 3.字节输出流。
             */
    
            PrintStream out = new PrintStream("print.txt");
    
            // int by=read();
            // write(by);
    
            // out.write(97);//a-97,二进制为0110-0001
            out.write(610);// b-98,只写最低8位,610二进制为10 0110-0010
    
            // out.print(97);//97,保持表示形式。将97先变成字节串保持原样,再打印到目的地
    
            out.close();
    
        }
    
    }
    
    


    public class PrintWriter extends Writer
    向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。

    package cn.itcase.io.p4.print.demo;
    
    import java.io.BufferedReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    
    public class PrintWriterDemo {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
            /*
             * PrintWrite 字符打印流
             * 构造函数参数:
             * 1.字符串路径;
             * 2.File对象;
             * 3.字节输出流;
             * 4.字符输出流。
             */
            BufferedReader bufr = new BufferedReader(new InputStreamReader(
                    System.in));
            // PrintWriter out = new PrintWriter(System.out, true);// true,自动刷新
            PrintWriter out = new PrintWriter(new FileWriter("out.txt"), true);// true,自动刷新
    
            String line = null;
            while ((line = bufr.readLine()) != null) {
                if ("over".equals(line))
                    break;
                out.println(line.toUpperCase());
                // out.flush();
            }
            out.close();
            bufr.close();
        }
    
    }
    


    序列流-SequenceInputStream
    可以对多个流进行合并。(只负责源)
    public class SequenceInputStream extends InputStreamSequenceInputStream
    表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

    枚举和迭代:

    package cn.itcase.io.p4.sequence.demo;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.SequenceInputStream;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Enumeration;
    import java.util.Iterator;
    
    public class SequenceInputStreamDemo {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            /*
             * 需求:将1.txt、2.txt、3.txt文件中的数据合并到一个文件中
             */
            // Vector<FileInputStream> v=new Vector<FileInputStream>();
            //
            // v.add(new FileInputStream("1.txt"));
            // v.add(new FileInputStream("2.txt"));
            // v.add(new FileInputStream("3.txt"));
            ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
    
            for (int x = 1; x <= 3; x++) {
                al.add(new FileInputStream(x + ".txt"));
            }
    
            Enumeration<FileInputStream> en = Collections.enumeration(al);
    
            /*
             * final Iterator<FileInputStream> it=al.iterator();
             * 
             * Enumeration<FileInputStream> en=new Enumeration<FileInputStream>(){
             * 
             * @Override
             * public boolean hasMoreElements() {
             * return it.hasNext();
             * }
             * 
             * @Override
             * public FileInputStream nextElement() {
             * return it.next();
             * }
             * 
             * };
             */
    
            SequenceInputStream sis = new SequenceInputStream(en);
    
            FileOutputStream fos = new FileOutputStream("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();
        }
    
    }
    


    文件切割示例:

    package cn.itcast.io.p1.splitefile;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    /**
     * 文件切割器
     * @author chenchong
     *
     */
    
    public class SplitFileDemo {
    
        private static final int SIZE = 1024 * 1024;
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            File file = new File("c:\\0.bmp");
    
            splitFile(file);
        }
    
        public static void splitFile(File file) throws IOException {
            // 用读取流关联源文件
            FileInputStream fis = new FileInputStream(file);
    
            // 定义一个1M的缓冲区
            byte[] buf = new byte[SIZE];
    
            // 创建目的
            FileOutputStream fos = null;
    
            int len = 0;
            int count = 1;
    
            /*
             * 切割文件时,必须记录被切割文件的名称,以及切割出来的碎片文件的个数,以方便与合并。
             * 这个信息为了进行简单的描述,使用键值对的方式,用到了properties对象
             */
            Properties prop = new Properties();
    
            File dir = new File("c:\\partfiles");
            if (!dir.exists())
                dir.mkdirs();
    
            while ((len = fis.read(buf)) != -1) {
                fos = new FileOutputStream(new File(dir, (count++) + ".part"));
                fos.write(buf, 0, len);
                fos.close();
            }
    
            // 将被切割文件的信息保存到prop集合中
            prop.setProperty("partcount", count + "");
            prop.setProperty("filename", file.getName());
            fos = new FileOutputStream(new File(dir, count + ".properties"));
    
            // 将prop中的数据存储到文件中
            prop.store(fos, "save file info");
            fis.close();
        }
    
    }
    




    文件合并示例:

    package cn.itcast.io.p1.splitefile;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.SequenceInputStream;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Enumeration;
    import java.util.Properties;
    
    /**
     * 文件合并器
     * @author chenchong
     *
     */
    public class MergeFile {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            File dir = new File("c:\\partfiles");
            mergeFile(dir);
        }
    
        public static void mergeFile(File dir) throws IOException {
    
            /*
             * 获取指定目录下的配置文件对象
             */
            File[] files = dir.listFiles(new SuffixFilter(".properties"));
    
            if (files.length != 1)// 没有properties,则抛出异常
                throw new RuntimeException(dir + ",该目录下没有properties扩展名的文件或者不唯一");
    
            // 记录配置文件对象
            File confile = files[0];
    
            // 获取该文件中的信息===============================
            Properties prop = new Properties();
            FileInputStream fis = new FileInputStream(confile);
    
            prop.load(fis);
    
            String filename = prop.getProperty("filename");
            int count = Integer.parseInt(prop.getProperty("partcount"));
    
            // 获取该目录下的所有碎片文件============================
            File[] partFiles = dir.listFiles(new SuffixFilter(".part"));
            if (partFiles.length != (count - 1)) {
                throw new RuntimeException("碎片文件不符合要求,个数不对。应该是" + count + "个");
            }
    
            // 将碎片文件和流对象关联并存储到集合中
            ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
    
            for (int x = 0; x < partFiles.length; x++) {
                al.add(new FileInputStream(partFiles[x]));
            }
    
            // 将多个流合并成一个序列流
            Enumeration<FileInputStream> en = Collections.enumeration(al);
            SequenceInputStream sis = new SequenceInputStream(en);
    
            FileOutputStream fos = new FileOutputStream(new File(dir, filename));
    
            byte[] buf = new byte[1024];
    
            int len = 0;
            while ((len = sis.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
    
            fos.close();
            sis.close();
        }
    }
    


    过滤器:

    package cn.itcast.io.p1.splitefile;
    
    import java.io.File;
    import java.io.FilenameFilter;
    
    /**
     * 过滤器
     * @author chenchong
     *
     */
    public class SuffixFilter implements FilenameFilter {
    
        private String suffix;
        public SuffixFilter(String suffix) {
            super();
            this.suffix = suffix;
        }
        @Override
        public boolean accept(File dir, String name) {
            return name.endsWith(suffix);
        }
    
    }
    



    操作对象
    ObjectInputStream、ObjectOutputStream。
    被操作的对象需要实现Serializable(标记接口)。

    public interface Serializable
    类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

    public final void writeObject(Object obj) throws IOException
    将指定的对象写入 ObjectOutputStream。对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都将被写入

    package cn.itcast.io.p1.objectstream;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    import cn.itcast.io.p2.bean.Person;
    
    public class objectStreamDemo {
    
        /**
         * @param args
         * @throws IOException
         * @throws ClassNotFoundException
         */
        public static void main(String[] args) throws IOException,
                ClassNotFoundException {
    
            // writeObj();
            readObj();
        }
    
        public static void readObj() throws IOException, ClassNotFoundException {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                    "obj.object"));
            // 对象的反序列化
            Person p = (Person) ois.readObject();
    
            System.out.println(p.getName() + ":" + p.getAge());
    
            ois.close();
    
        }
    
        public static void writeObj() throws IOException {
    
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
                    "obj.object"));
    
            // 对象的序列化。被序列化的对象必须实现Serializalbe接口
            oos.writeObject(new Person("小强", 30));
    
            oos.close();
        }
    
    }
    
    package cn.itcast.io.p2.bean;
    
    import java.io.Serializable;
    
    /*
     * Serializable用于给被序列化的类加入序列号
     * 用于判断类和对象是否是同一版本
     */
    public class Person implements Serializable/* 标记接口 */{
    
        /**
         * transient,非静态数据,又不想被序列化,可以使用该关键字修饰。
         */
        private static final long serialVersionUID = 9527L;
        private transient String name;// transient修饰的成员,不写入硬盘
        private int age;
    
        public Person(String name, int age) {
            super();
            this.age = age;
            this.name = name;
        }
    
        public Person() {
            super();
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
    }
    



    RandomAccessFile
    随机访问文件,自身具备读写的方
    通过skipBytes(int x),seek(int x),来达到随机访问的目的。

    public class RandomAccessFile extends Objectimplements DataOutput, DataInput, Closeable
    此类的实例支持对随机访问文件的读取和写入。

    package cn.itcast.io.p3.randomfiles;
    
    import java.io.IOException;
    import java.io.RandomAccessFile;
    
    public class RandomAccessFileDemo {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            /*
             * RandomAccessFile
             * 不是IO体系中的子类;
             * 特点:
             * 1.该对象既能读,又能写;
             * 2.该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素;
             * 3.可以通过getFilePointer获取指针的位置,通过seek方法设置指针的位置;
             * 4.其实,该对象就是将字节输入流和输出流进行了封装;
             * 5.该对象的源或者目的只能是文件,通过构造函数就可以看出;
             */
    
            // writeFile();
            // readFile();
            randomWrite();
    
        }
    
        public static void randomWrite() throws IOException {
            RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "rw");
    
            // 往指定位置写入数据
            raf.seek(3 * 8);
    
            raf.write("赵六".getBytes());
            raf.writeInt(102);
    
            raf.close();
        }
    
        public static void readFile() throws IOException {
            RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "r");
    
            // 通过seek设置指针的位置
            raf.seek(1 * 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);
    
            System.out.println("pos:" + raf.getFilePointer());
    
            raf.close();
        }
    
        // 使用RandomAccessFile对象写入一些人员信息
        public static void writeFile() throws IOException {
            /*
             * 如果文件不存在,则创建;如果文件存在,则不创建。
             */
            RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "rw");
    
            raf.write("张三".getBytes());
            // raf.write(609);//只保留低8位
            // raf.writeInt(609);//先写高位
            raf.writeInt(97);
            // raf.write("小强".getBytes());
            // raf.writeInt(98);
    
            raf.close();
        }
    
    }
    


    管道流

    PipedInputStream、PipedOutputStream

    输入输出可以直接进行连接,通过结合线程使用

    package cn.itcast.io.p4.piped;
    
    import java.io.IOException;
    import java.io.PipedInputStream;
    import java.io.PipedOutputStream;
    
    public class PipedStream {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
    
            PipedInputStream input=new PipedInputStream();
            PipedOutputStream output=new PipedOutputStream();
            
            input.connect(output);
            
            new Thread(new Input(input)).start();
            new Thread(new Output(output)).start();
            
        }
    
    }
    
    class Input implements Runnable {
    
        private PipedInputStream in;
    
        Input(PipedInputStream in) {
            this.in = in;
        }
    
        public void run() {
    
            try {
                Thread.sleep(5000);
                byte[] buf = new byte[1024];
                int len = in.read(buf);
    
                String s = new String(buf, 0, len);
                System.out.println("s=" + s);
                in.close();
            } catch (Exception e) {
            }
        }
    }
    
    class Output implements Runnable {
        private PipedOutputStream out;
    
        Output(PipedOutputStream out) {
            this.out = out;
        }
    
        public void run() {
            try {
                out.write("Hey,管道来了!".getBytes());
            } catch (Exception e) {
            }
        }
    }
    
    

    操作基本数据类型
    DataInputStream、DataOutputStream

    package cn.itcast.io.p5.datastream;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class DataStreamDemo {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            // writeData();
            readData();
        }
    
        public static void readData() throws IOException {
    
            DataInputStream dis = new DataInputStream(new FileInputStream(
                    "data.txt"));
    
            String str = dis.readUTF();
            System.out.println(str);
            dis.close();
        }
    
        public static void writeData() throws IOException {
    
            DataOutputStream dos = new DataOutputStream(new FileOutputStream(
                    "data.txt"));
    
            dos.writeUTF("你好");
    
            dos.close();
        }
    
    }
    


    操作字节数组
    ByteArrayInputStream、ByteArrayOutputStream
    public class ByteArrayOutputStream extends OutputStream
    此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。

    public class ByteArrayInputStream extends InputStreamByteArrayInputStream
    包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。
    关闭 ByteArrayOutputStream、ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。 (没有调用底层资源)

    package cn.itcast.io.p6.bytestream;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    
    public class ByteArrayStreamDemo {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
    
            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.toString());
            // bos.close();//无效,不需要关闭
        }
    
    }
    



    简单的编码解码

    package cn.itcast.io.p7.encode;
    
    import java.io.UnsupportedEncodingException;
    
    public class EncodeDemo {
    
        /**
         * @param args
         * @throws UnsupportedEncodingException
         */
        public static void main(String[] args) throws UnsupportedEncodingException {
    
            /*
             * 字符串——>字节数组,编码
             * 字节数组——>字符串,解码
             * 你好(GBK):-60 -29 -70 -61
             * 你好(UTF-8):-28 -67 -96 -27 -91 -67
             * 
             * 如果编码错误,解码不出来
             * 如果编码正确,解码有可能解出
             */
    
            String str = "你好";// -60 -29 -70 -61
    
            byte[] buf = str.getBytes("gbk");
    
            String s1 = new String(buf, "iso8859-1");//查表错误
            System.out.println("s1=" + s1);//解码错误
            
            byte[] buf2 = s1.getBytes("iso8859-1");//获取源字节
            String s2=new String(buf2,"gbk");//重新解码
            System.out.println("s2="+s2);
    
            // encodeDemo(str);
    
        }
    
        /**
         * @param str
         * @throws UnsupportedEncodingException
         */
        public static void encodeDemo(String str)
                throws UnsupportedEncodingException {
            // 编码
            byte[] buf = str.getBytes("utf-8");
            // printBytes(buf);
    
            // 解码
            String s1 = new String(buf);
            System.out.println("s1=" + s1);
        }
    
        public static void printBytes(byte[] buf) {
            for (byte b : buf) {
                System.out.print(b);
            }
        }
    
    }
    


    练习-按字节截取字符串

    package cn.itcast.io.p7.encode;
    
    import java.io.IOException;
    
    /*
     * 在java中,字符串"abcd",与字符串"ab你好"的长度是一样的,都是四个字符。
     * 但相应的字节数不同,一个汉字占两个字节。
     * 定义一个方法,按照最大的字节数来取子串。
     * 如:对于"ab你好",如果去三个字节,那么子串就是ab与“你”字的半个,
     * 那么半个就要舍弃。如果取四个字节就是"ab你",去五个字节还是"ab你"
     */
    public class Test {
    
        /**
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
    
            String str = "ab你好cd谢谢";
            // String str = "ab琲琲cd琲琲";// 琲,-84 105
    
            // int len = str.getBytes("gbk").length;
            // for (int x = 0; x < len; x++) {
            // System.out.println("截取" + (x + 1) + "个字节结果是:"
            // + cutStringByBytes(str, x + 1));
            // }
    
            int len = str.getBytes("utf-8").length;
            for (int x = 0; x < len; x++) {
                System.out.println("截取" + (x + 1) + "个字节结果是:"
                        + cutStringByU8Bytes(str, x + 1));
            }
        }
    
        public static String cutStringByU8Bytes(String str, int len)
                throws IOException {
    
            byte[] buf = str.getBytes("utf-8");
    
            int count = 0;
            for (int x = len - 1; x >= 0; x--) {
                if (buf[x] < 0)
                    count++;
                else
                    break;
            }
    
            if (count % 3 == 0)// utf-8码,三个字节组成
                return new String(buf, 0, len, "utf-8");
            else if (count % 3 == 1)
                return new String(buf, 0, len - 1, "utf-8");
            else
                return new String(buf, 0, len - 2, "utf-8");
    
        }
    
        public static String cutStringByBytes(String str, int len)
                throws IOException {
    
            byte[] buf = str.getBytes("gbk");
    
            int count = 0;
            for (int x = len - 1; x >= 0; x--) {
                if (buf[x] < 0)
                    count++;
                else
                    break;
            }
    
            if (count % 2 == 0)
                return new String(buf, 0, len, "gbk");
            else
                return new String(buf, 0, len - 1, "gbk");
        }
    }
  • 相关阅读:
    线程池的实现原理
    log4j 具体解说(不能再具体了)
    MyEclipse中背景颜色的设定
    cacheManager载入问题
    SAP 经常使用T-CODE
    Oracle 版本号说明
    用XMPP实现完整Android聊天项目
    选择如何的系统更能适合App软件开发人员?
    爱国者布局智能硬件,空探系列PM2.5检測仪“嗅霾狗”大曝光
    Innodb引擎状态查看
  • 原文地址:https://www.cnblogs.com/chenchong/p/2638752.html
Copyright © 2011-2022 走看看