常见到的文件与流-输入与输出

java网络方面的输出/入流。

  1. http协义下:DataOutputStream ,BufferedReader,InputStreamReader,InputStream.
    ------InputStream,OutputStream这两个流是字节流,很不好用。一般是保存文件用它。而读取显示时用BufferedReader字符流。
    -----输出流,注入数据到https请求报文中,以post请求方式访问远程服务器。再通过输入流获取数据到本地保存为一个文件中。
    本示例:访问一个远程jsp页面内容保存到本地中,java项目为javanetModule1,文件Demo5.java,远程服务器项目qihangkttest---IndexController.java,WEB-INF-jsp-index1.jsp。
/**
 * 该类功能:测试:post ,get请求服务器的区别(web服务器是:springmvc项目:qihangkttest,IndexController.java index1.jsp)
 * @author x
 *
 */
public class Demo5 {
   public static void main(String args[]) throws Exception {
       String urlPath = "http://localhost/qihangkt/postIndex.html";
       //要提交给服务器的数据,汉字要编码(
       String param = "name="+URLEncoder.encode("熊少文","UTF-8");
       //建立连接
       URL url = new URL(urlPath);
       HttpURLConnection conn= (HttpURLConnection) url.openConnection();
       //设置参数
       conn.setDoOutput(true);   //post请求,它是把数据塞到https协议中报文中,所以我们要设置true允许修改输出。
       conn.setDoInput(true);
       conn.setUseCaches(false);
       conn.setRequestMethod("POST");
       
       
       //设置请求头信息
       conn.setRequestProperty("Charset", "UTF-8");
       conn.setRequestProperty("Connection", "Keep-Alive"); //长连接
       conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
       
       //获取到输出流,才能把param放到请求体(报文中)
       conn.connect();
       DataOutputStream dos=new DataOutputStream(conn.getOutputStream());  //数据输出流
       dos.writeBytes(param);
       dos.flush();                    //真正塞进去
       dos.close();
       
       
       //获取服务器响应回来的信息
       int resultcode = conn.getResponseCode();
       if(resultcode == HttpURLConnection.HTTP_OK) {
           BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
           String line = null;
           while((line = reader.readLine())!=null) {
               System.out.println(line);
           }
       }
   }
}

IndexController.java---(spring mvc知识见简书相关资料)

@Controller
public class IndexController {
    @GetMapping(value= {"/index.html","/","index"})
   public String index() {
       return "index";
   }
    
    @RequestMapping(value= {"/getIndex.html"},method=RequestMethod.GET)
    public String getIndex(Model model,HttpServletRequest request) {
        model.addAttribute("name","get请求过来的值--"+request.getParameter("name"));
        return "index1";
     }
    @RequestMapping(value="/postIndex.html",method=RequestMethod.POST)
    public String postIndex(Model model,HttpServletRequest request) throws UnsupportedEncodingException {
        request.setCharacterEncoding("UTF-8");
        model.addAttribute("name","post请求过来的值--"+request.getParameter("name"));
        System.out.println(request.getParameter("name"));
        return "index1";
    }
}

index1.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <title>测试get请求与post请求区别</title>
</head>
<body>
 用户传过来的值:<h2>${name}</h2> 
</body>
</html>

测试:运行Demo5.java主函数

image.png

  1. http协议下:RandomAccessFile可以创建文件保存任何类型的文件,这里我们保存图片
    项目:javanetModuel1
    文件:下载保存工具类 DownUtil.java 测试类:Demo4.java
    DownUtil具有多线程功能,可以在创建该类对象时定义线程数。
public class DownUtil {
    //首先需要的东西,要知道下载的目标文件的URL
    private String urlPath;
    //确定保存文件的位置
    private String targetFile;
    //确定下载用几条线程
    private int threadNum;
    //定义一个数组,放的是下载的线程类
    private DownThread[] threads;
    //把用于下载的线程类定义为工具里的内部类
    private class DownThread extends Thread{
        //线程类里边的具体实现
        private int startPos;   //开始位置(下载)
        private int currentPartSize;//当前负责的块大小
        private RandomAccessFile currentPart;  //当前下载的文件块
        //记录每条线程已经下载下来的文件的字节数
        private int length;
        public DownThread(int startPos,int currentPartSize,RandomAccessFile currentPart) {
            this.startPos = startPos;
            this.currentPartSize = currentPartSize;
            this.currentPart = currentPart;
        }
        @Override
        public void run() {
            
            try {        //类内部异常不可直抛出
                URL url = new URL(urlPath);
                HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                //真正链接目标之前,要设置头部信息。
                conn.setConnectTimeout(5000);  //5秒后不链接
                conn.setRequestMethod("GET");   //GET就够了,只是一个字符串(文件名)请求。
                conn.setRequestProperty("Accept", "*/*");   //客户端可处理任何文件
                conn.setRequestProperty("Accept-Language", "zh-CN");
                conn.setRequestProperty("Charset", "UTF-8");
                conn.setRequestProperty("Connection", "Keep-Alive"); //保持TCP连接暂时不断
                //前面设置这么多东西,一个目的。取得目标文件的大小
                //链接上目标
                conn.connect();   //可不写
                InputStream in=conn.getInputStream();
                //把in的指针,跳到该线程负责下载的位置
                in.skip(this.startPos);
                byte[] buffer =new byte[1024];
                int hasRead =0;
                while(length<currentPartSize && (hasRead=in.read(buffer))!=-1) {  //线程下载不能大于当前负责块的大小,也不下载完毕后再下载(最后一个线程考滤的)
                    currentPart.write(buffer,0,hasRead);
                    length+=hasRead;
                }
                currentPart.close();
                in.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
            
        }
    }
    //保存一下目标文件的大小
    private int fileSize;
    
    //构造器,让外界调用
    public DownUtil(String urlPath,String targetFile,int threadNum) {
        this.urlPath=urlPath;
        this.targetFile=targetFile;
        this.threadNum = threadNum;
        this.threads = new DownThread[threadNum];   //初始化线程个数
    }
        
    //定义一个实现下载文件的方法
    public void download() throws Exception {  //工具类一般我们挽出异常,不用try catch.Exception是最大的异常类
        //第一件事儿,获取目标文件的大小
        URL url = new URL(urlPath);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        //真正链接目标之前,要设置头部信息。
        conn.setConnectTimeout(5000);  //5秒后不链接
        conn.setRequestMethod("GET");   //GET就够了,只是一个字符串(文件名)请求。
        conn.setRequestProperty("Accept", "*/*");   //客户端可处理任何文件
        conn.setRequestProperty("Accept-Language", "zh-CN");
        conn.setRequestProperty("Charset", "UTF-8");
        conn.setRequestProperty("Connection", "Keep-Alive"); //保持TCP连接暂时不断
        //前面设置这么多东西,一个目的。取得目标文件的大小
        //链接上目标
        conn.connect();
        fileSize = conn.getContentLength();  //获取目标大小
        conn.disconnect();    //用了以后,及时关掉资源通道
        //根据文件的大小和下载线程数量,来进行目标文件切块
        //先在本地创建一个和目标文件大小的文件。
        RandomAccessFile file = new RandomAccessFile(targetFile, "rw");//RandomAccessFile唯一父类是Object,与其他流父类不同。是用来访问那些保存数据记录的文件的,这样你就可以用seek( )方法来访问记录,并进行读写了。
        file.setLength(fileSize);
        file.close();
           //每个线程负责下载的文件块的大小
        int currentPartSize = fileSize/threadNum+1;  //例:500B分5块,起始址:0-101,102-202..。
        for(int i=0;i<threadNum;i++) {
            //设置每个线程下载文件块的开始值
            int startPos = i*currentPartSize;
            //让每个线程使用一个RandomAccessFile的对象来进行下载
            RandomAccessFile currentPart = new RandomAccessFile(targetFile, "rw");
            //每个线程负责下载的文件块
            currentPart.seek(startPos); //移动文件指针,找到下载位置
            threads[i] =new DownThread(startPos,currentPartSize,currentPart);
            //让线程启动,开始下载
            threads[i].start();
        }
    }
    //获取下载完成的百分比
    public double getCompleteRate() {
        int sumSize = 0;
        for(int i=0;i<threadNum;i++) {
            sumSize+=threads[i].length;
            
        }
        return sumSize *1.0/fileSize;
    }
}

public class Demo4 {
  public static void main(String args[]) throws Exception {
      DownUtil downUtil = new DownUtil("https://qcloud.dpfile.com/pc/47nSY2z-B4uD9sQCvj-.jpg","c:\\xiong/aaa.jpg", 5);
      downUtil.download();  //下载
      new Thread(new Runnable() {
        
        @Override
        public void run() {
            while(downUtil.getCompleteRate()<=1) {
                System.out.println("已下载:  "+downUtil.getCompleteRate());
                try {
                    Thread.sleep(10);
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
        }
    }).start();
  }
}

  1. Socket实现服务器与客户端互通
    ----本实例应用BufferedReader字符输入流读取请求数据,显示到控制台中。
    套接字
    在网络上很多应用程序都是采用客户端/服务器(C/S)的模式,实现网络通信必须将两台计算机连接起来建立一个双向的通信链路,这个双向通信链路的每一端在Java的网络编程中,我们又称之为一个套接字(Socket)。套接字(Socket)是一个抽象出来的概念代表在端上的通信链路。
    ----上面的只是一端请求web,再响应客户,没有互通功能。
    socket会先在服务器端阻塞,等客户端有请求,马上响应,可以实时给客户。

Server.java

public class Server {
    public static void main(String[] args) throws IOException {
        //根据流程第一步,创建ServerSocket
        ServerSocket serverSocket = new ServerSocket(); //无参数,表示socket没有链接到任何设备上
        serverSocket.bind(new InetSocketAddress("127.0.0.1",40000));  //链接到本机,端口号40000
        //用一个循环来不断的接收客户端的链接
        while(true) {
            //接收客户端的链接请求,
            Socket clientSocket=serverSocket.accept();   //此方法会阻塞,直到客户端有请求为止,他会返回一个与连进来的客户端一一对应的socket
            //通过clientSocket对应的输入流来接收数据
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));//InputStream该流是字节码流,很不好用,所以别建字符流
            //通过in获取客户端发来的信息
            String str = in.readLine();
            System.out.println("客户端发来的信息: "+str);
            
            
            //发送信息
            PrintStream ps = new PrintStream(clientSocket.getOutputStream(),true,"UTF-8");  //ture自动flush,'GBK'表示DOS用的中文码
            ps.println("我是服务器!");
            
            ps.close();
            clientSocket.close();
        }
    }

}

Client.java

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket();  //无参,默认连接本机
        socket.connect(new InetSocketAddress("127.0.0.1",40000));
        
        //发送数据
        PrintStream ps=new PrintStream(socket.getOutputStream(),true,"UTF-8");
        ps.println("我是客户端");
        
        //接收数据
        BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
        String str=in.readLine();
        System.out.println("服务器端发送来的数据是: "+str);
        in.close();
        ps.close();
        socket.close();
    }

}

测试:先运行Server.java 的main方法,serverSocket.accept();会阻塞,直到客户端有请求为止,再运行Client.java的main方法

image.png

文件I/O操作

----要把程序所处理的数据在不同的内存容器(内存或外存)进行传输,例如将内存数据写到外存上(某个文件中),就要用到I/O(输入/输出流)技术。JAVA中,所有的I/O机制都是基于数据‘流’方式进入输入/输出。
---这些流序列中的数据通常有两种方式:文本流与二进制流。
---Java语言中定义了许多专门负责各种方式的输入/输出,这些类都被放在java.io包中:有标准输入 /输出,文件的操作,网络上的数据流,字符串流和对象流等。

1-File文件类

----File类主要是JAVA为文件这块的操作(如删除、新建等)而设计的相关类File类的包名是java.io,其实现了Serializable, Comparable两大接口以便于其对象可序列化和比较。
----File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法重点:记住这第三个单词
file——文件
directory——文件夹/目录
path——路径
彻底搞明白绝对路径和相对路径
绝对路径————是一个完整的路径,如以盘符( 比如C:)开始的路径
c:\a.txt
c:\demo\b.txt
相对路径————是一个简化的路径
相对指的是相对于当前项目的根目录
如果使用当前项目的根目录,路径可以简化书写
'D:\java\Java语言高级\File类\File类\File类的概述.avi'–--------->简化为'File类的概述.avi'(可以省略项目的根目录)
java项目中,相对路径一般指英目根目录。
下面是几种获取路径的方法'/'是项目根目录,该项目在C:\Users\x\Desktop\STSWORKSPACE\中

/**
 * 路径的测试:windows 中 d:\\a.txt.
 * @author x
 *
 */
public class FileTest1 {
          public static void main(String args[]) {
              FileTest1 fileTest1 = new FileTest1();
              try {
                fileTest1.getUrl();
            } catch (IOException e) {
                
                e.printStackTrace();

            }
          }
          
          public void getUrl() throws IOException {
              //1.使用类加载路径(反射)
              String path="";
              path=this.getClass().getResource("/").getPath();
              System.out.println("1: "+path);               //编译后的.class存放的根目录
              path= this.getClass().getResource("").getPath();
              System.out.println("当在类所在的路径,是加载类不是源码java:"+path);
              
              
              //2.利用File类获取相关路径
              File file = new File("");
              path = file.getCanonicalPath();
             // path= file.getAbsolutePath();
              System.out.println(path);                    //项目根目录
              
              //3.实际上还是第一种方法
              URL path1 =this.getClass().getResource("");
              System.out.println(path1);                 //file:/C:/Users/x/Desktop/STSWORKSPACE/javanetModule1/bin/cn/ybzy/demo/File/
              
              
              //4.利用System类
              path = System.getProperty("user.dir");
              System.out.println("4:"+path);  //C:\Users\x\Desktop\STSWORKSPACE\javanetModule1
         
              //5.利用线程
              path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
              System.out.println("5:线程获取路径: "+path);    ///C:/Users/x/Desktop/STSWORKSPACE/javanetModule1/bin/
          
              //6.在web项目中,request
              //request.getSession().getServletContext().getRealPath("/"));   //根的绝对路径
          }
}

注意
1.路径是不区分大小写
2.路径中的文件名称分隔符widows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通反斜杠。

public class FileProperties {
     public static void main(String args[]) {
         System.out.println("File属性读取path路径分隔符   "+File.pathSeparator);   //windows中是分号,在LINUX中运行此程序为冒号 :(path变量中的分隔符)
         System.out.println("File属性读取path路径分隔符  "+File.pathSeparatorChar);
         
         
         System.out.println(File.separator);                                      //winodws中显示为反斜杠 '\',Linux中显示为'/',所以我们写创建文件是为了跨平台,最好写成带属性的样子。
         //File file = new File("C:"+File.separator+"a.txt");
        // File file =new File("xiong/a.txt");             //项目根目录下的xiong目录下创建a.txt文件
         
        File file = new File("D:\\xiong"); //或 File file = new File("D:/xiong");
         try {
            //file.createNewFile();          //发生IOException,该异常对创建目录不起作用。
             file.mkdir();                     //创建目录不发生异常
        } catch (Exception e) {
            
            e.printStackTrace();
        }
         
         System.out.println(File.separatorChar);

        // File file2 = new File("xiong\\shao\\wen");  //创建多级目录
         File file2 = new File("d:/iotest/xiong/shao/wen");
         file2.mkdirs();
     //遍历(文件)目录
    /*   File file3 = new File("d:/iotest/xiong/shao/wen");
         String[] fileName = file3.list();
         File[] files = file3.listFiles();
         for(String filename:fileName) {
             System.out.println("文件名:"+filename);
         }
         for(File subFile:files) {
             System.out.println(subFile);                  //不会拿到wen子目录下的文件
         }*/
         
         //遍历所有文件,过滤器过滤java扩展名的文件
         File file4 = new File("D:/iotest/xiong/shao/wen");
         getJavaFiles(file4);   //调用过滤器,只显示所有扩展名为.java的文件。
     }
     //过滤器,过滤所有java类文件
     public static  void getJavaFiles(File file) {
         if(!file.isDirectory()) {
             return;                    //如果不是文件夹,不作任何操作
         }
         
         //是文件夹
         File[] files = file.listFiles(new FileFilter() {
            
            @Override
            public boolean accept(File subFile) {
                //在这个方法体写上过滤规则 1,子目录。2,java文件
                if(subFile.isDirectory()) {
                    return true;
                }else {
                   return subFile.getName().toLowerCase().endsWith(".java");
                }
            }
        });
         //过滤后的结果文 件我要看看
         for(File rsFile:files) {
             if(rsFile.isDirectory()) {
                 getJavaFiles(rsFile);   //使用递归来进入更深层次的文件夹
             }else {
                 System.out.println(rsFile);
             }
         }
     }
}

测试:我们把一个项目根目所所有文 件复制到wen目录下,再运行主方法在控制台可以看到效果,如下两图

image.png

image.png

File类常用的方法

public class Filefangfa {
    public static void main(String args[]) {
        File file = new File("D:/iotest/xiong/shao/wen/a.txt");    //并不在硬盘上创建文件,需要像 FileProperties.java那样搞,目录由 mkdir创建
        System.out.println(file.getName());
        System.out.println(file.getPath());                //获取相对路径,当路径写成绝对路径形式,下面两个方法返回一样的内容
        System.out.println(file.getAbsolutePath());        //D:\iotest\xiong\shao\wen\a.txt
        
//      File file = new File("xiong1");
//      System.out.println(file.getName());
//      System.out.println(file.getPath());                //xiong    ,获取相对路径,当路径写成绝对路径形式,下面两个方法返回一样的内容
//      System.out.println(file.getAbsolutePath());        //C:\Users\x\Desktop\STSWORKSPACE\javanetModule1\xiong
        
        System.out.println("父目录:"+file.getParent());            //D:\iotest\xiong\shao\wen 当a.txt是目录的话,这里会显示D:\iotest\xiong\shao\wen\a.txt 当然了windows中不会这样显示但linux中会显示
        //file.renameTo(new File("C:\\Users\\x\\Desktop\\STSWORKSPACE\\javanetModule1\\xiong2"));   //为文件改名
        
        
        //文件检查有关的方法
        System.out.println("文件是否存在:"+file.exists());
        System.out.println("日录吗?:"+file.isDirectory());  //是否为目录
        System.out.println("目录没做一个文看待:"+file.isFile());       //目录没做一个文件看待
        System.out.println("能写吗:"+file.canWrite());      //文件能写吗
        System.out.println("能读吗:  "+file.canRead());
        System.out.println("是绝对路径吗"+file.isAbsolute());    //是绝对路径吗
        
        
        System.out.println("文件的长度: "+file.length());
      // file.delete();                               //删除文件,不会放到回收站,小心使用,不会产生异常,不管有没有文件
    } 

}

////////////////////////////////////////////////////////结果//////////////////////////////////////////////
a.txt
D:\iotest\xiong\shao\wen\a.txt
D:\iotest\xiong\shao\wen\a.txt
父目录:D:\iotest\xiong\shao\wen
文件是否存在:true
日录吗?:false
目录没做一个文看待:true
能写吗:true
能读吗:  true
是绝对路径吗true
文件的长度: 0

Java IO流

---大多数应用程序都需要实现与设备之间的数据传输,例如键盘可以输入数据,显示器可以显示程序的运行结果等。
---在Java中,将这种通过不同输入输出设备(键盘,内存,显示器,网络等)之间的数据传输抽象的表述为“流”。
---Java中的“流”都位于java.io包中,称之为IO(输入输出)流。
输入流和输出流是相对于内存设备而言的,将外设中的数据读取到内存中即输入,将内存的数据写入到外设中即输出。
IO流的分类:
---按照不同的分类方式,可以把流分为不同的类型。常用的分类有三种:
一,按照流的流向分,可以分为输入流和输出流。
输入流: 只能从中读取数据,而不能向其写入数据。
输出流:只能向其写入数据,而不能向其读取数据。
此处的输入,输出涉及一个方向的问题,数据从内存到硬盘,通常称为输出流

image.png

此处的输入,输出涉及一个方向的问题,数据从内存到硬盘,通常称为输出流
数据从服务器通过网络流向客户端,在这种情况下,Server端的内存负责将数据输出到网络里,


image.png

因此Server端的程序使用输出流;
Client端的内存负责从网络中读取数据,因此Client端的程序应该使用输入流。
注:java的输入流主要是InputStream和Reader作为基类,而输出流则是主要由outputStream和Writer作为基类。它们都是一些抽象基类,无法直接创建实例。
二,按照操作单元划分,可以划分为字节流和字符流。
---字节流和字符流的用法几乎完成全一样,区别在于字节流和字符流所操作的数据单元不同,字节流操作的单元是数据单元是8位的字节,字符流操作的是数据单元为16位的字符。
---字节流主要是由InputStream和outPutStream作为基类,而字符流则主要有Reader和Writer作为基类。
三,按照流的角色划分为节点流和处理流。
---可以从/向一个特定的IO设备(如磁盘,网络)读/写数据的流,称为节点流。 节点流也被称为低级流。

image.png

---处理流则用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能。 处理流也被称为高级流。


image.png

当使用处理流进行输入/输出时,程序并不会直接连接到实际的数据源,没有和实际的输入和输出节点连接。使用处理流的一个明显的好处是,只要使用相同的处理流,程序就可以采用完全相同的输入/输出代码来访问不同的数据源
打个比方在进一步理解流的概念
java把所有设备里的有序数据抽象成流模型,简化了输入/输出处理。java IO流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java Io流的40多个类都是从如下4个抽象类基类中派生出来的。
《1》InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
《2》OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
对于InputStream和Reader而言,它们把输入设备抽象成为一个”水管“,这个水管的每个“水滴”依次排列,如图

image.png

输入流使用隐式的记录指针来表示当前正准备从哪个“水滴”开始读取,每当程序从InputStream或者Reader里面取出一个或者多个“水滴”后,记录指针自定向后移动;除此之外,InputStream和Reader里面都提供了一些方法来控制记录指针的移动。
对于OutputStream和Writer而言,它们同样把输出设备抽象成一个”水管“,只是这个水管里面没有任何水滴,如图
image.png

当执行输出时,程序相当于依次把“水滴”放入到输出流的水管中,输出流同样采用隐示指针来标识当前水滴即将放入的位置,每当程序向OutputStream或者Writer里面输出一个或者多个水滴后,记录指针自动向后移动。
处理流可以“嫁接”在任何已存在的流的基础之上,这就允许Java应用程序采用相同的代码,透明的方式来访问不同的输入和输出设备的数据流。

字节流和字符流的基类方法

IO体系的基类(InputStream/Reader,OutputStream/Writer)
字节流和字符流的操作方式基本一致,
只是操作的数据单元不同——字节流的操作单元是字节,字符流的操作单元是字符。
所以字节流和字符流就整理在一起了。
InputStream/Reader,OutputStream/Writer是所有输入/输出流的抽象基类,
本身并不能创建实例来执行输入/输出,
但它们将成为所有输入/输出流的模板,
所以它们的方法是所有输入/输出流都可使用的方法。
在InputStream里面包含读数据的方法。
一。int read(); 从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转换为int类型)。
二。int read(byte[] b)从输入流中最多读取b.length个字节的数据,并将其存储在字节数组b中,返回实际读取的字节数。
三。int read(byte[] b,int off,int len); 从输入流中最多读取len个字节的数据,并将其存储在数组b中,放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字节数。
在Reader中包含也有如下3个方法。
一,int read(); 从输入流中读取单个字符,返回所读取的字符数据(字符数据可直接转换为int类型)。
二,int read(char[] b)从输入流中最多读取b.length个字符的数据,并将其存储在字节数组b中,返回实际读取的字符数。
三,int read(char[] b,int off,int len); 从输入流中最多读取len个字符的数据,并将其存储在数组b中,放入数组b中时,并不是从数组起点开始,而是从off位置开始,返回实际读取的字符数。
对比InputStream和Reader所提供的方法,就不难发现这两个基类的功能基本是一样的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容