美文网首页
java笔记--IO包中的其他类

java笔记--IO包中的其他类

作者: 吃饱喝足搬代码丶 | 来源:发表于2018-11-21 19:04 被阅读0次
    打印流:PrintWriter,PrintStream--可以直接操作输入流和文件。

    PrintWriter:字符打印流。
    构造函数:
    1,字符串路经。
    2,File对象。
    3,字符输出流。
    4,字节输出流。
    PrintStream:提供了打印方法可以对多种数据类型值进行打印,并保持数据的表现形式,不抛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(610);//只写最低8位,
            
            out.print(97);//将97先变成字符保持原样将数据打印到目的地。
            
            out.close();
        }
    
    运行:

    SequenceInputStream:序列流--对多个流进行合并。

    public class SequenceInputStreamDemo {
        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"));
    //      Enumeration<FileInputStream> en = v.elements();
            
            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("1234.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 SplitFileDemo {
    
        private static final int SIZE = 1024 * 1024;
    
        public static void main(String[] args) throws Exception {
    
            File file = new File("c:\\a.mp3");
    
            splitFile_2(file);
        }
    
        private static void splitFile_2(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");
    
            fos.close();
            fis.close();
    
        }
    
        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;
    
            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();
            fis.close();
    
        }
    }
    
    运行:

    合并文件:

    public class MergeFile {
        public static void main(String[] args) throws IOException {
    
            File dir = new File("c:\\partfiles");
            
            mergeFile_2(dir);
        }
        
        public static void mergeFile_2(File dir) throws IOException {
            
            /*
             * 获取指定目录下的配置文件对象。
             */
            File[] files = dir.listFiles(new SuffixFilter(".properties"));
            
            if(files.length!=1)
                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();
            
            
            
            
            
            
        }
    
        public static void mergeFile(File dir) throws IOException{
            
            
            ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
            
            for(int x=1; x<=3 ;x++){
                al.add(new FileInputStream(new File(dir,x+".part")));
            }
            
            Enumeration<FileInputStream> en = Collections.enumeration(al);
            SequenceInputStream sis = new SequenceInputStream(en);
            
            FileOutputStream fos = new FileOutputStream(new File(dir,"2.mp3"));
            
            byte[] buf = new byte[1024];
            
            int len = 0;
            while((len=sis.read(buf))!=-1){
                fos.write(buf,0,len);
            }
            
            fos.close();
            sis.close();
            
        }
    }
    
    运行:

    ObjectInputStream与ObjectOutputStream:操作对象,但是被操作的对象需要实现Serializable。
    Serializable:用于给被序列化的类加入ID号,用于判断类和对象是否是同一个版本。

    public class Person implements Serializable/*标记接口*/ {
    
        private static final long serialVersionUID=9527l;//Serializable使得类每次改动都会生成不同的序列号,所以会发生InvalidClassException.这里给固定一个序列,解决问题。
        private String name;//可改动变量修饰符试一下是否抛出InvalidClassException.
        private int age;
        
        
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        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;
        }
    }
    
    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, IOException {
            
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));
            //对象序列化。  被序列化的对象必须实现Serializable接口。 
            oos.writeObject(new Person("小强",30));
            
            oos.close();
    
        }
    }
    
    运行:

    transient:非静态数据不想序列化可使用这个关键字修饰。
    writeObject:对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都可被写入。

    public class Person implements Serializable/*标记接口*/ {
    
        /**
         * transient:非静态数据不想被序列化可以使用这个关键字修饰。
         */
        private static final long serialVersionUID = 9527l;
        private transient String name;
        private static int age;//静态不可被写入
        
        
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        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;
        }   
    }
    
    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, IOException {
            
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));
            //对象序列化。  被序列化的对象必须实现Serializable接口。 
            oos.writeObject(new Person("小强",30));
            
            oos.close();
    
        }
    }
    
    运行:

    RandomAccessFile:随机访问文件,自身具备读写的方法。通过skipBytes(int x),seek(int x)来达到随机访问。
    因为可以随机写入,所以写文件可用多线程同时进行读写操作。

    public class RandomAccessFileDemo {
    
        public static void main(String[] args) throws IOException {
            /*
            RandomAccessFile:
                1,该对象既能读,又能写
                2,该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素
                3,可以通过getFilePointer方法获取指针位置,通过seek方法设置指针位置
                4,其实该对象就是将字节输入流和输出流进行了封装。
                5,该对象的源或者目的只能是文件。可通过构造函数看出。
                */
            
    //      writeFile();
            readFile();
        }
        
        public static void readFile() throws IOException {
            
            RandomAccessFile raf=new RandomAccessFile("ranacc.txt","r");
            
            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();
        }
    
        //使用RandomAccessFile对象写入一些人员信息,比如姓名,年龄
        public static void writeFile() throws IOException {
            
    //      如果文件不存在,则创建,存在则不创建
            RandomAccessFile raf=new RandomAccessFile("ranacc.txt","rw");//rw:打开以便读取和写入,若文件不存在,尝试创建
            
            raf.write("张三".getBytes());
            raf.writeInt(97);
            raf.write("小强".getBytes());
            raf.writeInt(99);
            
            raf.close();
        }
    }
    
    运行:
    public static void randomWrite() throws IOException {
            RandomAccessFile raf=new RandomAccessFile("ranacc.txt","rw");
            
            //往指定位置写入数据
            raf.seek(3*8);
            
            raf.write("哈哈".getBytes());
            raf.writeInt(108);
            
            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();
        }
    
    运行:

    PipedInputStream,PipedOutputStream:管道流,输入输出可以直接进行连接,通过结合线程使用。

    public class PipedStream {
    
        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 {
                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 {
                Thread.sleep(5000);
                out.write("hi,管道来了!".getBytes());
            } catch (Exception e) {
            }
        }
    }
    
    运行:

    DataInputStream,DataOutputStream:操作基本数据类型。

    public class DataStreamDemo {
    
        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);
        }
    
        public static void writeData() throws IOException {
            
            DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
            
            dos.writeUTF("你好");
            
            dos.close();
        }
    }
    
    运行:

    ByteArrayReader,CharArrayWrite:操作字节数组。
    CharArrayReader,CharArrayWrite:操作字符数组。
    StringReader,StringWriter:操作字符串。

    public class ByteArrayStreamDemo {
    
        public static void main(String[] args) {
            
            ByteArrayInputStream bis=new ByteArrayInputStream("abcdef".getBytes());
            
            ByteArrayOutputStream bos=new ByteArrayOutputStream();
            
            int ch=0;
            
            while((ch=bis.read())!=-1){
                bos.write(ch);
            }
            System.out.println(bos.toString());
        }
    
    }
    
    运行:

    字符编码:字符流的出现是为了方便操作字符,更重要的是加入了编码转换--通过子类转换流完成--InputStreamReader,OutputStreamWriter。在两个对象进行构造的时候可以加入字符集。

    public class EncodeDemo {
    
        public static void main(String[] args) throws IOException {
            /*
            字符串 -->字节数组:编码。
            字节数组 -->字符串:解码。
            */
            
            String str="谢谢";
            
            byte[] buf=str.getBytes("gbk");
            
            String s1=new String(buf,"UTF-8");
            
            System.out.println("s1="+s1);
            
            byte[] buf2=s1.getBytes("UTF-8");//获取源字节。
            
            printBytes(buf2);
            
            String s2=new String(buf2,"GBK");
            
            System.out.println("s2="+s2);
            
            encodeDemo(str);
        }
    
        public static void encodeDemo(String str) throws UnsupportedEncodingException {
            //编码
            byte[] buf=str.getBytes("UTF-8");
            
            printBytes(buf);
            
            //解码
            String s1=new String(buf,"UTF-8");
            
            System.out.println("s1="+s1);
        }
    
        public static void printBytes(byte[] buf) {
            for(byte b:buf){
                System.out.print(b+" ");
            }
            
        }
    }
    
    运行:

    联通问题(utf-8修改版字节表现形式):


    新建文本
    保存后再打开
    原因:保存时,默认系统编码方式,打开时以utf-8的方式打开。

    验证:

    public class LianTong {
    
        public static void main(String[] args) throws IOException {
            String str="联通";
            
            byte[] buf=str.getBytes("gbk");
            
            for(byte b:buf){
                System.out.println(Integer.toBinaryString(b&255));
            }
    
        }
    }
    
    运行:

    截取字符:

    public class Test {
    
        public static void main(String[] args) throws IOException {
            
            String str="ab你好cd谢谢";
    //      str="ab琲琲cd琲琲";
            
            /*int len=str.getBytes("gbk").length;
            for(int x=0;x<len;x++){
                System.out.println("截取"+(x+1)+"个字节结果是:"+cutStringByByte(str,x+1));
            }*/
            
            int len=str.getBytes("utf-8").length;
            for(int x=0;x<len;x++){
                System.out.println("截取"+(x+1)+"个字节结果"+cutStringByU8Byte(str,x+1));
            }
            
            /*String str="琲";
            byte[] buf=str.getBytes("gbk");
            for(byte b:buf){
                System.out.println(b);
            }*/
        }
        /*
        在java中,字符串"abcd"与字符串"ab你好"的长度是一样的,都是四个字符。
        但对应的字节数不同,一个汉字占两个字节。
        定义一个方法,按照最大的字节数来取子串。
        如:对于"ab你好",如果取三个字节,那么子串就是ab与"你"字的半个,没那
        么半个就要舍弃。如果去四个字节就是"ab你",取五个字节还是"ab你"。
        */
    
        public static String cutStringByU8Byte(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)
                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 cutStringByByte(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");
        }
    }
    
    运行:

    相关文章

      网友评论

          本文标题:java笔记--IO包中的其他类

          本文链接:https://www.haomeiwen.com/subject/opxbfqtx.html