zoukankan      html  css  js  c++  java
  • Java I/O

    I/O操作

    流的作用:为数据源和目的地建立一个输送通道。
    
    
    磁盘操作:File
    	File 类可以用于表示文件和目录的信息,但是它不表示文件的内容。
    
    
    字节操作:InputStream 和 OutputStream(二进制格式操作)
    	InputStream:抽象类。基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
    	OutputStream:抽象类。基于字节的输出操作,是所有输出流的父类。定义了所有输出流都具有的共同特征。
    
    
    字符操作:Reader 和 Writer(文件格式操作)
    	Reader:抽象类,基于字符的输入操作。
    	Writer:抽象类,基于字符的输出操作。
    
    
    RandomAccessFile(随机文件操作):
    
    	一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。
    
    
    对象操作:Serializable
    
    
    网络操作:Socket
    
    
    新的输入/输出:NIO
    

    I/O流分类

    根据处理数据类型的不同分为:字符流和字节流
    
    据数据流向不同分为:输入流和输出流
    
    按数据来源(去向)分类:
    
    	1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter
    
    	2、byte[]: ByteArrayInputStream, ByteArrayOutputStream
    
    	3、Char[]:  CharArrayReader,CharArrayWriter
    
    	4、管道操作: PipedInputStream、PipedOutputStream、PipedReader、PipedWriter
    
    	5、网络数据流: InputStream,OutputStream, Reader, Writer
    
    	6、打印:PrintStream、PrintWriter
    
    	7、对象序列化反序列化:ObjectInputStream、ObjectOutputStream
    
    	8、转换:InputStreamReader、OutputStreWriter
    
    	9、缓冲操作:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter
    

    字符流与字节流

    字节流读取单个字节,字符流读取单个字符。
    
    
    字符转字节:
    	byte[] bytes = string.getBytes("UTF-8");
    字节转字符:
    	String s = new String(byte bytes[], int offset, int length, String charsetName);
    
    
    字符流使用了缓冲区(关闭字符流时会强制性地将缓冲区中的内容进行输出),而字节流没有使用缓冲区(不关闭字节流也可以输出):
    	在字符流的操作中,所有的字符都是在内存中形成的,在输出前会将所有的内容暂时保存在内存之中,所以使用了缓冲区暂存数据。
    	如果想在不关闭时也可以将字符流的内容全部输出,则可以使用Writer类中的flush()方法完成。
    
    
    InputStreamReader(InputStream in):将字节流以字符流输入。
    OutputStreamWriter(OutputStream out):将字节流以字符流输出。
    
    将UTF-8转换成GBK:
    
    	FileInputStream fis = new FileInputStream("a.txt");
    	InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
    
    	FileOutputStream fos = new FileOutputStream("b.txt");
    	OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
    
    
    只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。
    
    
    编码与解码:
    	编码就是把字符转换为字节,而解码是把字节重新组合成字符。
    
    
    char 类型占 16 位,也就是两个字节,Java 使用这种双字节编码是为了让一个中文或者一个英文都能使用一个 char 来存储。
    
    
    Reader 与 Writer:
    	不管是磁盘还是网络传输,最小的存储单元都是字节,而不是字符。
    	但是在程序中操作的通常是字符形式的数据,因此需要提供对字符进行操作的方法。
    
    
    逐行读取文件内容
    
        public static void readFileContent(String filePath) throws IOException {
    
            FileReader fileReader = new FileReader(filePath);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
    
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
    
            // 装饰者模式使得 BufferedReader 组合了一个 Reader 对象
            // 在调用 BufferedReader 的 close() 方法时会去调用 Reader 的 close() 方法
            // 因此只要一个 close() 调用即可
            bufferedReader.close();
        }
    

    装饰(Decorator)设计模式

    在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。
    
    适用性:
    	需要扩展一个类的功能,或给一个类添加附加职责。
    	当不能采用生成子类来实现,比如final类。
    
    
    装饰者和被装饰者之间必须是一样的类型,也就是要有共同的超类:
        FileInputStream fileInputStream = new FileInputStream(filePath);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
    
    
    抽象构件(Component)
    
    public abstract class InputStream implements Closeable {
    	public abstract int read() throws IOException;
    }
    
    
    具体构件(Concrete Component)
    
    public class FileInputStream extends InputStream {
    	public int read() throws IOException {
            return read0();
        }
    	private native int read0() throws IOException;
    }
    
    
    抽象装饰(Decorator):内部一定要有一个指向具体构件对象的引用
    
    public class FilterInputStream extends InputStream {
        protected volatile InputStream in;
    
        protected FilterInputStream(InputStream in) {
            this.in = in;
        }
    
        public int read(byte b[], int off, int len) throws IOException {
            return in.read(b, off, len);
        }
    }
    
    
    具体装饰(ConcreteDecorator):添加附加的责任
    
    public class BufferedInputStream extends FilterInputStream {
        private static int DEFAULT_BUFFER_SIZE = 8192;
        protected volatile byte[] buf;
    
        public BufferedInputStream(InputStream in, int size) {
            super(in);
            if (size <= 0) {
                throw new IllegalArgumentException("Buffer size <= 0");
            }
            buf = new byte[size];
        }
    }
    

    文件复制

    public class CopyTest {
    
        public static void main(String[] args) throws IOException {
            File file1 = new File("E:\PE系统.rar");
            File file2 = new File("E:\PE系统_copy.rar");
            copyTest(file1, file2);
        }
    
        private static void copyTest(File file1, File file2) throws IOException {
            FileInputStream fis = null;	//输入流
            FileOutputStream fos = null;	//输出流
    
            try {
                fis = new FileInputStream(file1);
                fos = new FileOutputStream(file2);
    
                //创建缓冲流,提高字节流的操作效率
                BufferedInputStream bis = new BufferedInputStream(fis);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
    
                int len = 0;
                byte[] bytes = new byte[4096];
                //返回 -1 的时候表示读到 eof,即文件尾
                while ((len = bis.read(bytes)) != -1) {
                    bos.write(bytes, 0, len);
                    bos.flush();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
                if (fis != null)
                    fis.close();
                if (fos != null)
                    fos.close();
            }
        }
    }
    

    文件分割

    class SplitFile {
        public static void main(String[] args) throws Exception {
            /**
             * 文件切割器
             */
            File file = new File("E:\1.mp4");
            File desFile = new File("E:\split");
            if (!desFile.exists()) {
                desFile.mkdirs();
            }
            splitFile(file, desFile);
        }
    
        private static void splitFile(File file, File desFile) throws IOException {
            // 读取源文件
            FileInputStream fis = new FileInputStream(file);
            // 创建目的(输出流每生成一个文件都需要重新构建一下)
            FileOutputStream fos = null;
    
            // 创建一个缓冲区
            byte[] by = new byte[1024 * 1024 * 10];
            int len = 0;
            int count = 0;
            while ((len = fis.read(by)) != -1) {
                // 创建输出流,明确写入文件的对象
                File partFile = new File(desFile, (++count) + ".part");
                fos = new FileOutputStream(partFile);
                fos.write(by, 0, len);
                fos.close();
            }
    
            // 创建配置文件
            File configFile = new File(desFile, "config.properties");
            if (!configFile.exists()) configFile.createNewFile();
            // 载入配置文件
            Properties pro = new Properties();
            pro.setProperty("partcount", Integer.toString(count));
            pro.setProperty("filename", file.getAbsolutePath());
            //输出配置文件
            fos = new FileOutputStream(configFile);
            pro.store(fos, "切割文件配置信息");
            fos.close();
            fis.close();
        }
    }
    

    压缩文件

    class ZipTest {
        public static void main(String[] args) throws IOException {
            File file1 = new File("E:\表白神器1");  //源文件
            String path = file1.getName();  //源文件名
            File file2 = new File("E:\表白神器.zip");  //目的文件
    
            //打开输出流
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file2));
    
            //需要用到递归
            zip(zos, file1, path);
            zos.close();
        }
    
        private static void zip(ZipOutputStream zos, File file1, String path) throws IOException {
            if (file1.isDirectory()) {
                File[] filer = file1.listFiles();   //当前目录下的所有文件or目录
                if (filer.length == 0) {    //当前目录是空目录
                    zos.putNextEntry(new ZipEntry(path + "/"));    //如果文件夹为空,则只需写入一个目录
                } else {    //如果文件夹不为空,则递归调用,文件夹中的每一个文件(或文件夹)进行压缩
                    for (File f : filer) {
                        zip(zos, f, path + "/" + f.getName());
                        System.out.println(path + "/" + f.getName());
                    }
                }
            } else {
                zos.putNextEntry(new ZipEntry(path));   //写入文件(表白神器/新建文件夹/表白神器.TXT)
    
                //打开输入流
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file1));
                //输出到Zip文件
                byte[] by = new byte[1024];
                int len;
                while ((len = bis.read(by)) != -1) {
                    zos.write(by, 0, len);
                    zos.flush();
                }
                bis.close();
            }
        }
    }
    

    对象操作

    序列化:
    	序列化就是将一个对象转换成字节序列,方便存储和传输。
    
    序列化:ObjectOutputStream.writeObject()
    反序列化:ObjectInputStream.readObject()
    
    
    不会对静态变量进行序列化,因为序列化只是保存对象的状态,静态变量属于类的状态。
    
    
    Serializable:
    	序列化的类需要实现 Serializable 接口。
    
    
    transient 关键字可以使一些属性不会被序列化。
    
    ArrayList 中存储数据的数组 elementData 是用 transient 修饰的,因为这个数组是动态扩展的,并不是所有的空间都被使用,
    因此就不需要所有的内容都被序列化。
    通过重写序列化和反序列化方法,使得可以只序列化数组中有内容的那部分数据。
    private transient Object[] elementData;
    

    网络操作

    InetAddress:用于表示网络上的硬件资源,即 IP 地址
    	没有公有的构造函数,只能通过静态方法来创建实例:
    		InetAddress.getByName(String host);
    		InetAddress.getByAddress(byte[] address);
    
    URL:统一资源定位符
    
    Sockets:使用 TCP 协议实现网络通信
    
    Datagram:使用 UDP 协议实现网络通信
    
    
    URL:可以直接从 URL 中读取字节流数据。
    
    public static void main(String[] args) throws IOException {
    
        URL url = new URL("http://www.baidu.com");
    
        /* 字节流 */
        InputStream is = url.openStream();
    
        /* 提供缓存功能 */
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8"));
    
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    
        br.close();
    }
    
  • 相关阅读:
    Ant.OutputIsUnreadableCode
    Android.HowToDesignPluginArchitectureInAndroidApp
    Java.FamousBlogs
    Java.WeakReference-SoftReference-PhantomReference
    DataStructure.BloomFilter
    Android.HowToDefineCustomView
    Android.Study.Question
    Android.PublishApplication
    Android.Libraries
    Site.AboutHardware
  • 原文地址:https://www.cnblogs.com/loveer/p/11797891.html
Copyright © 2011-2022 走看看