美文网首页
#IO复习学习

#IO复习学习

作者: ZalleDay | 来源:发表于2019-03-03 20:26 被阅读0次

    IO复习学习

    IO

    在Java IO中,流是一个核心的概念。流从概念上来说是一个连续的数据流。你既可以从流中读取数据,也可以往流中写数据。流与数据源或者数据流向的媒介相关联。在Java IO中流既可以是字节流(以字节为单位进行读写),也可以是字符流(以字符为单位进行读写)。

    类InputStream, OutputStream, Reader 和Writer

    一个程序需要InputStream或者Reader从数据源读取数据,需要OutputStream或者Writer将数据写入到目标媒介中。以下的图说明了这一点:

    [图片上传中...(image-42c2cd-1551613113798-0)]

    InputStream和Reader与数据源相关联,OutputStream和writer与目标媒介相关联。

    Java IO的用途和特征

    Java IO中包含了许多InputStream、OutputStream、Reader、Writer的子类。这样设计的原因是让每一个类都负责不同的功能。这也就是为什么IO包中有这么多不同的类的缘故。各类用途汇总如下:

    • 文件访问
    • 网络访问
    • 内存缓存访问
    • 线程内部通信(管道)
    • 缓冲
    • 过滤
    • 解析
    • 读写文本 (Readers / Writers)
    • 读写基本类型数据 (long, int etc.)
    • 读写对象

    当通读过Java IO类的源代码之后,我们很容易就能了解这些用途。这些用途或多或少让我们更加容易地理解,不同的类用于针对不同业务场景。

    图谱

    IO的一些小例子

      public void InputStreamTest(){
            try {
                //InputStream用于读取基于字节的数据,一次读取一个字节,这是一个InputStream的例子:
                //字节流需要强转char
                System.out.println("in InputStream : ");
                InputStream inputStream = new FileInputStream("IOtest.txt");
                int date =  inputStream.read();
                while (date != -1){
                    System.out.print((char) date);
                    date = inputStream.read();
                }
                System.out.print("\n");
                inputStream.close();
            }catch (Exception e){
                System.out.println(e.getMessage() + " error");
            }
        }
    
        public void InputStreamWithBuffer(){
            try {
                InputStream inputStream = new FileInputStream("IOtest.txt");
                byte[] buffer = new byte[1024];
                int data = inputStream.read(buffer);
                while (data!=-1){
                    for (int i = 0; i < data; i++)
                        System.out.print((char) buffer[i]);
                    data = inputStream.read(buffer);
                }
    
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
        }
    
        public void OutputTest() {
            try {
                byte bWrite[] = { 11, 21, 3, 40, 5 };
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                outputStream.write("hello world!!".getBytes());
    
                byte[] buf = outputStream.toByteArray();
                for (int i = 0; i < 11; i++)
                    System.out.print((char)buf[i]);
    
            } catch (IOException e) {
                System.out.print(e.getMessage());
            }
    
        }
    

    read()
    read()方法返回从InputStream流内读取到的一个字节内容(0~255),例子如下:

    int data = inputstream.read();
    你可以把返回的int类型转化成char类型:

    char aChar = (char) data;
    InputStream的子类可能会包含read()方法的替代方法。比如,DataInputStream允许你利用readBoolean(),readDouble()等方法读取Java基本类型变量int,long,float,double和boolean。

    流末尾
    如果read()方法返回-1,意味着程序已经读到了流的末尾,此时流内已经没有多余的数据可供读取了。-1是一个int类型,不是byte或者char类型,这是不一样的。

    当达到流末尾时,你就可以关闭流了。

    read(byte[])
    InputStream包含了2个从InputStream中读取数据并将数据存储到缓冲数组中的read()方法,他们分别是:

    int read(byte[])
    int read(byte, int offset, int length)
    一次性读取一个字节数组的方式,比一次性读取一个字节的方式快的多,所以,尽可能使用这两个方法代替read()方法。

    read(byte[])方法会尝试读取与给定字节数组容量一样大的字节数,返回值说明了已经读取过的字节数。如果InputStream内可读的数据不足以填满字节数组,那么数组剩余的部分将包含本次读取之前的数据。记得检查有多少数据实际被写入到了字节数组中。

    read(byte, int offset, int length)方法同样将数据读取到字节数组中,不同的是,该方法从数组的offset位置开始,并且最多将length个字节写入到数组中。同样地,read(byte, int offset, int length)方法返回一个int变量,告诉你已经有多少字节已经被写入到字节数组中,所以请记得在读取数据前检查上一次调用read(byte, int offset, int length)的返回值。

    这两个方法都会在读取到达到流末尾时返回-1。

    个人疑问

    之前不知道字节流和字符的使用场景,知道写了一个图片上传的功能才有点清除。
    字节流 FileInputStream FileOutputStream
    字符流 FileReader FileWriter
    字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点.
    所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列.
    字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 2. 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。

    public String saveImage(MultipartFile file) throws IOException {
            int dotPos = file.getOriginalFilename().lastIndexOf(".");
            if (dotPos < 0) {
                return null;
            }
            String fileExt = file.getOriginalFilename().substring(dotPos + 1).toLowerCase();
            if (!ToutiaoUtil.isFileAllowed(fileExt)) {
                return null;
            }
            String fileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + fileExt;
            Files.copy(file.getInputStream(), new File(ToutiaoUtil.IMAGE_DIR + fileName).toPath(),
                    StandardCopyOption.REPLACE_EXISTING);
            return ToutiaoUtil.TOUTIAO_DOMAIN + "image?name=" + fileName;
        }
    

    相关文章

      网友评论

          本文标题:#IO复习学习

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