zoukankan      html  css  js  c++  java
  • javaIO

    JAVA IO

    java.io.File类

    java对文件和目录的操作

    java.io.File类用于表示文件或者目录。

    对于File类的对象的操作实际就为对存储介质中的文件和目录的操作。

    File类的文件操作与操作系统平台无关。

    1. 构造方法

      public File(String pathname)以pathname为路径创建File对象。

    2. 常用属性

      public static final String separator: 存储当前系统的路径分隔符。UNIX:'/',Windows:'\'。为了跨平台文件路径应用这个属性代替。

    3. 访问属性的方法

      • public boolean canRead():判断文件是否可读

      • public boolean canWrite(): 判断文件是否可写

      • public boolean exits(): 判断文件是否存在

      • public boolean isDirectory():判断是否是目录

      • public boolean isFile(): 判断是否为文件

      • public boolean isHidden(): 判断文件是否隐藏

      • public long lastModified(): 返回最后修改的时间

      • public long length(): 返回文件以字节为单位的长度

      • public String getName():获取文件名

      • public String getPath():获取文件的路径

      • public String getAbsolutePath():获取此文件的绝对路径名。

      • public String getCanonicalPath():获取此文件的规范路径名。

      • public File getAbsoluteFile(): 得到绝对路径规范表示的文件对象。

      • public String getParent():得到文件的父目录路径名

      • public URL toURL():返回此文件的统一资源标识符名

        public static void main(String[] args) throws IOException {
            File file = new File("D:\IOTest\source.txt");//指定目录要存在改文件
            
            
        }
        
    4. 对文件的操作

      • public boolean createNewFile(): 不存在时常见此文件对象所代表的空文件。
      • public boolean delete():删除文件。必须目录为空才能删除
      • public boolean mkdir():创建此抽象路径指定的目录。
      • public boolean mkdirs(): 创建此抽象路径指定的目录,同时创建父目录
      • public boolean renameTo(File dest):重新命名为此抽象路径表示的文件
    5. 浏览目录中的文件和子目录方法

      • public String[] list(): 返回此目录中的文件和目录名的数组
      • public File[] listFiles(): 返回此目录中的文件和目录的File实例数组
      • public File[] listFiles(FilenameFilter filter): 返回此目录中满足指定过滤器的文件和目录
      public static void main(String[] args) throws IOException{
          File dir1 = new File("D:/IOTest/dir1");
          if (!dir1.exists()) dir1.mkdir();//不存在就创建
          File dir2 = new File(dir1, "dir2");//以dir1为父目录 名字为dir2
          
          File dir4 = new File(dir1, "dir3/dir4");//以dir1,dir3为父目录 创建名字为dir4的目录
          
          File file = new File(dir2, "test.txt");
          if (!file.exists()) file.createNewFile();//不存在就创建
          
          deleteAll(dir1);//删除目录
      }
      
      public static void deleteAll(File file){
          if (file.isFile()) {
              file.delete();//直接删除文件
              return;
          }
          //是目录 则递归删除子目录和子文件
      	File[] lists = file.listFile();
          
          for (int i = 0; i < lists.length; i++) {
              deleteAll(list[i]);//则递归删除子目录和子文件
          }
          System.out.println("删除目录:"+ file.getAbsolutePath());
          file.delete();
      }
      

    java IO原理

    从数据源读数据时就要开启一个到数据源的流。

    方便处理数据的输入输出。

    流式结构

    1. 按数据流向
      • 输入流:程序可能从中读取数据的流
      • 输出流:程序可能从中输出数据的流
    2. 按数据传输单位
      • 字符流:传输单位为字符
      • 字节流:传输单位为字节
    3. 按流的功能
      • 节点流:用于直接操作数据源的流
      • 过滤流:处理流,对一个已经存在流的连接和封装,读写功能更强大

    java.io包中四种抽象流类:

    • 字节流:
      • InputStream
      • OutputStream
    • 字符流:
      • Reader
      • Writer

    InputStream和OutputStream

    1. InputStream

      以字节为单位从数据源中读取数据

      • public abstract int read() throws IOException: 从输入流中读取数据的下一个字节,返回读到的字节值。流的末尾返回-1
      • public void close() throws IOException:关闭输入流并释放系统资源
    2. OutputStream

      以字节为单位向数据源写数据

      • public abstract void write(int b) throws IOException:将指定的字节写入输出流
      • public void write(byte[] b) throws IOException: 将b.length个字节从指定的byte数组写入此输出流
      • public void flush() throws IOException :刷新此输出流,并强制写出所有缓冲的输出字节
      • public void close() throws IOException:关闭输入流并释放系统资源

    Reader和Writer

    1. Reader

      以字符为单位从数据源中读取数据

      • public abstract int read() throws IOException: 从输入流中读取数据的字符,返回读到的字符值。流的末尾返回-1
      • public void close() throws IOException:关闭输入流并释放系统资源
    2. Writer

      以字符为单位向数据源写数据

      • public abstract void write(int b) throws IOException:将指定的字符写入输出流
      • public void write(char[] cbuf) throws IOException: 写入字符数组
      • public void write(String str) throws IOException:写入字符串
      • public void flush() throws IOException :将缓冲数据全部写到目的地
      • public void close() throws IOException:先刷新再关闭

    文件流

    FileInputStream、FileOutputStream、FileReader、FileWriter四个文件流。

    1. FileInputStream、FileOutputStream

      import java.io.*
      
      public static void main(String[] args) {
      	FileInputStream fin = null;
      	
      	try {
      		// 第一步:创建一个FileInputStream对象
      		fin = new FileInputStream("D:\IOTest\source.txt");
      		System.out.println("可读取的字节数" + fin.available());
      		//第二步:按字节读数据,返回的是读到的字节
      		int i = read();
      		while(i != -1) {
      			System.out.println((char)i);
      			i = fin.read();
      		}
      	} catch (FileNotFoundException e) {
      		e.printStackTrace();
      	} catch (IOException e) {
      		e.printStackTrace();
      	} finally {
      		try {
      			if (null != fin)
      				fin.close();//关闭输入流
      		} catch (IOException e) {
      			e.printStackTrace();
      		}
      		
      	}
      }
      

      Java字符采用Unicode,汉字占用两个字节,英文字符占一个用字节流读取会出乱码问题。

      import java.io.*
      
      public static void main(String[] args) {
      	FileInputStream out = null;
      	try {
      		//1.建立连接
      		out = new FileInputStream("D:\IOTest\source.txt");
      		//2.写数据
      		out.write("#");
      		out.write("hello word".getBytes());//字符串转换为字节数组
      		out.write("你好".getBytes());//字符串转换为字节数组
      		//3.刷新输出流
      		out.flush();
      	} catch (FileNotFoundException e) {
      		e.printStackTrace();
      	} catch (IOException e) {
      		e.printStackTrace();
      	} finally {
      		try {
      			if (null != out)
      				out.close();//关闭输入流
      		} catch (IOException e) {
      			e.printStackTrace();
      		}
      	}
      }
      

      IO流类的close方法会释放占有的系统资源,用来操作二进制文件比较合适,图片,声音,视频等二进制文件。

    2. FileReader、FileWriter

      以字符为操作单位的文件输入流和文件输出流。

      常用于操作字符文本文件。

      //实现字符文本的复制
      import java.io.*
      
      public static void main(String[] args) {
      	FileReader fr = null;
      	FileWriter fw = null;
      	int c = 0;
      	
      	try {
      		fr = new FileReader("D:\IOTest\source.txt");
      		fw = new FileWriter("D:\IOTest\result.txt");
      		
      		while((c = fr.read()) != -1) {
      			fw.write(c);
      		}
      		fw.flush();
      	} catch (FileNotFoundException e) {
      		e.printStackTrace();
      	} catch (IOException e) {
      		e.printStackTrace();
      	} finally {
      		try {
      			if (null != fw)
      				fw.close();//关闭输入流
      			if (null != fr)
      				fr.close();//关闭输入流
      		} catch (IOException e) {
      			e.printStackTrace();
      		}
      	}
      }
      

      为了更高的效率可以一次提取一个字节数组和写入一个字节数组。

      int length = 0;//字符串长度
      char []cbuf = new char[8192];
      while((length = fr.reader(cbuf)) != -1) {
          fw.write(cbuf, 0, length);//一次性写入
      }
      

    缓冲流

    为了提高读写速率,提供带缓冲功能的流类,内部创建一个缓冲区数组。读取数据时,先把数据填充到该内部缓冲区,然后再返回;在写入数据前先放到缓冲区再一次性写入到目标数据源。

    • BufferedInputStream 和 BufferedOutputStream:针对字节的缓冲输入和输出流
    • BufferedReader和BufferedWriter:针对字符的缓冲输入和输出流

    属于过滤流,不直接操作数据源,是对直接操作数据源的节点流的一个包装。

    //用缓冲流来改写字符文本复制功能
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedReader bw = null;
        
        try {
            //创建缓冲流对象:是过滤流,是对节点流的包装
            br = new BufferedReader(new FileReader("D:\IOTest\source.txt"));
            bw = new BufferedWriter(new FileWriter("D:\IOTest\source.txt"));
            
            String str = null;
            while ((str = br.readLine()) != null) { // 每次读取一行字符
                bw.write(str); //一次写入一行字符串
                bw.newLine(); //写入行分隔符
            }
            bw.flush();
        }
    }
    

    关闭过滤流时会自动关闭所包装的底层节点流。

    转换流

    在字节和字符流之间转换。

    InputStreamReader和OutputStreamWriter。

    1. InputStreamReader

      将字节流中读取到的字节按指定字符集解码成字符,需要和InputStream套接

      • InputStreamReader(InputStream in):使用默认字符集的InputStreamReader
      • InputStreamReader(InputStream in, String charsetName):使用指定字符集的InputStreamReader
    2. OutputStreamWriter

      将要写入字节流的字符按指定字符集编码成字节,需要和OutputStream套接

      • OutputStreamWriter(OutputStream in):使用默认字符编码的OutputStreamWriter
      • OutputStreamWriter(OutputStream out, String charsetName):使用指定字符编码的OutputStreamWriter
    public static void main(String[] args) {
        System.out.println("输入信息:按e或exit退出");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = null;
        try {
            while(s = br.readLine() != null) {
                if (s.equalsIgnoreCase("e")||s.equalsIgnoreCase("exit")) {
                    System.out.println("安全退出!!");
                    break;
                }
                System.out.println("-->:" + s.toUpperCase());
                System.out.println("输入信息:按e或exit退出");
            }
        } catch {//异常处理
            ...
        }
    }
    

    先把字节流包装成字符流,为了进一步提高效率,又把它包装成缓冲流。

    数据流

    为了方便操作java语言的基本数据类型的数据,可以使用数据流。

    DataInputStream和DataOutputStream分别来读写出基本数据类型

    • public final boolean readBoolean(): 从输入流中读取一个布尔型的值。
    • public final byte readByte(): 从输入流中读取一个8位的字节
    • public final char readChar(): 读取一个16位的Unicode字符
    • public final float readFloat(): 读取一个32位的单精度浮点数
    • public final double readDouble(): 读取一个64位的双精度浮点数
    • public final short readShort(): 读取一个16位的短整数
    • public final int readInt(): 读取一个16位的短整数
    • public final long readLong(): 读取一个64位的长整数
    • public final void readFully(byte[] b): 从当前输入流中读取b.length个字节到该字节数组
    • public final void readFully(byte[] b, int off, int len): 从当前数据流中读取len个字节到字节数组
    • public final String readUTF(): 读取一个UTF格式字符组成的字符串
    • public int skipBytes(int n): 跳过n字节
    public static void main(String[] args) {
        DataOutputStream dos = null;
        try {
            //创建连接到指定文件的数据输出流对象
            dos = new DataOutoutStream(new FileOutputStream("d:\IOTest\destData.dat"));
            dos.writeUTF("ab 中国");
            dos.writeBoolean(false);
            dos.writeLong(12345678L);
        }
    }
    
    

    打印流

    PrintStream和PrintWriter都属于打印流,提供一系列的print和println方法,可以实现将基本数据类型的数据格式转换成字符串进行输出。

    PrintStream和PrintWriter不会抛出IOException异常

    public class void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(new File("d:\IOTest\text.txt"));
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        }
        //创建打印输出流,设置为自动刷新模式(写入换行或字节'
    '都会刷新输出缓冲区)
        PrintStream ps = new PrintStream(fos, true);
        if (ps != null) {
            //把标准输出流(控制台输出)改成文件
            System.setOut(ps);
        }
        for (int i = 0; i <= 255; i++) {
            System.out.print((char)i);
            if (i % 50 == 0) {
                System.out.println();//换行
            }
        }
        ps.close();
    }
    
    

    对象流

    ObjectOutputStream和ObjectInputStream类是用于存储和读取基本数据类型或对象的过滤流,可以把Java 的对象写入到数据源中,也能把对象从数据源中还原回来。

    用ObjectOutputStream保存基本数据类型或对象的机制叫做序列化。

    用ObjectInputStream读取基本数据类型或对象的机制叫做反序列化。

    ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量,能被序列化的对象所对应的类必须实现java.io.Serializable这个标识性接口。

    public class Student implements java.io.Serializable {
        private int id;
        private String name;
        private transient int age; //在序列化的时候不会被保存和读取
        public Student(){}
        public student(int id, int age, String name) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
        public int getId() {return id;}
        public int getAge() {return age;}
        public String toString() {return "id="+id ,",name="+name,",age="+age;}
    }
    
    
    //创建一个学生对象并序列化到一个文件objectSeri.dat
    
    public static void main(String[] args) {
        ObjectOutputStream oos = null;
        try {
            // 创建连接到指定文件的对象输出流实例
            oos = new ObjectOutputStream(new FileOutputStream("D:\IOTest\objectSeri.dat"));
            oos.write(new Student(101, 22,"张三"));
            oos.flush(); //刷新输出流
            System.out.println("序列化成功");
        } catch ()//异常处理
    }
    
    
    //把指定文件中的数据反序列化回来,并打印输出它的信息
    public static void main(String[] args) {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("D:\IOTest\objectSeri.dat"));
            Student stu = (Student) ois.readObject();//读取对象
            System.out.println(stu);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            ois.close();
        }
    }
    
    

    随机存取文件流

    RandomAccessFile 是一个特殊的流类,它可以在文件的任何地方读取或写入数据。打开后可以进行只读操作或者读写操作。

    在第二个参数指定操作方式: r,rw,rws,rwd.

    RandomAccessFile in = new RandomAccessFile("d:\IOTest||music.wmv", "r");

    RandomAccessFile inout = new RandomAccessFile("d:\IOTest||music.wmv", "rwd");

    类似存在一个文件指针,该文件指针标志将要读写操作的下一个字节的位置, getFilePointer()方法可以返回文件指针的当前位置。seek方法可以将文件指针移动到文件内部的任意字节位置。

    随机存取文件流只能操作磁盘文件,不能访问来自网络或内存映像的流。

    RandomAccessFile类的多线程下载程序

    import java.io.*
    import java.net.*
    
    public class MutiThreadDownloadTest{
    	public static void main(String[] args) thorws IOException{
    		String urlStr = "http://...sss.mp3" ;//资源地址
    		URL url = new URL(urlStr);  //创建URL
    		URLConnection con = url.openConnection(); //建立连接
    		int contentLen = con.getContentLength(); //获取连接资源总长度
    		int threadQut = 10; //线程数
    		int subLen = contentLen / threadQut;// 每个线程要下载的大小
    		int remainder = contenLen % threadQut; // 余数
            File destFile = new File("D:\IOTest\sss.mp3"); //目标文件
            
            for (int i = 0; i < threadQut; i++) {
            	int start = subLen * i; //从目标文件的start位置开始写入到end结束总共subLen个字节
            	int end = start + subLen - 1; 
            	if (i == threadQut - 1) { //最后一次要加上余数
            		end += remainder;
            	}
            	Thread t = new Thread(new DownloadRunnable(start, end, url, destFile));//开启一个新线程
            	t.start();//启动新线程
            }
    	}
    }
    
    public class DownloadRunnale implements Runnable {
    	private final int start;
    	private final int end;
    	private final URL srcURL;
    	private final File destFile;
    	private static final int BUFFER_SIZE = 8192; //缓冲区大小
        public DownloadRunnale(int start, int end, URL srcURL, FILE destFile){
        	this.start = start;
        	this.end = end;
        	this.srcURL = srcURL;
        	this.destFile = destFile;
        }
        public void run() {
        	System.out.println("Thread.currentThread().getName()" + "启动");
        	BufferedInputStream bis = null;
        	RandomAccessFile ras = null;
        	byte[] buf = new byte[BUFFER_SIZE];
        	URLConnection con = null;
        	try {
        		con = srcURL.openConnection();
        		con.setRequestProperty("Range","byte="+start+"-"+end);
        		
        		bis = new BufferedInputStream(con.getInpputStream());
        		ras = new RandomAccessFile(destFile,"rw");
        		ras.seek(start);
        		int len = -1;
        		while ((len = bis.read(buf)) != -1) {
        			ras.write(buf, 0, len);
        		}
        		System.out.println(Thread.currentThread().getName() + "下载完毕"); 
        	}
        }
    }
    
    
  • 相关阅读:
    【负载均衡】1.负载均衡介绍
    1.tcpdump、wireshark常用用法
    10.prometheus PromQL
    9.prometheus pushgateway介绍与部署
    服装行业生产按客户订制的解决方案
    课程总结
    第十四周课程总结&实验报告
    第十三周学习总结
    第十二周总结
    时间过得好快,第十一周就要截止了。不该遗憾的,要开心,要努力。
  • 原文地址:https://www.cnblogs.com/DengSchoo/p/12831649.html
Copyright © 2011-2022 走看看