java的io流(同步阻塞式io流)


1.io流簡介

不論是Reader,Writer,還是InputStream,OutputStream,在創建相應的對象是只是創建了相應的映射,相當於修了一條馬路通向兩個位置,但是本身並不參與數據的傳輸,數據的傳輸是通過數組完成的,這個傳輸的過程是單向的(nio的buffer是雙向的)面向於流的傳輸(nio面向緩存數據塊),對於讀的時候不論基於單個字符還是基於數組,當沒有可讀的元素的時候返回值都是-1,有可讀的時候返回的是有效數據的字節或字符長度,返回字符串的時候,在沒有的情況下為null,對於一個輸入流來說具有skip的方法,跳到我們制定的地方去開始輸入,對於寫我們可以設置為true在尾部添加,對於覆蓋數據我們可以是用RandomAccessFile的seek設定覆蓋的位置,對於我們對象流(序列化流)可以將一個文件保存在一個文件中,然后在另一個地方讀取(讀取的前提條件是相應的序列化類需要已經加載到JVM中),對於BufferedOutputStream等采用裝飾模式,也就是在FileOutputStream外面包了一層,對於文件的亂碼問題前面有一篇有介紹。

2.file

public class CreateFile {
    // 創建文件
    public static void creatFile(String filePath) throws Exception {
        File file = new File(filePath);
        if (!file.exists()) {
            file.createNewFile();
        } else {
            System.err.println("文件夾以及存在");
        }
    }

    // 創建文件夾
    public static void creatFolder(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            file.mkdirs();
        } else {
            System.err.println("文件夾以及存在");
        }
    }

    // 在指定的文件下搜索文件(可以模糊查找)
    public static List<String> FuzzySearch(String filePath, String regex) {
        LinkedList<String> lls = new LinkedList<>();
        regex = ".*" + regex + ".*";
        File file = new File(filePath);
        if (!file.exists()) {
            System.err.println("指定的目錄不存在");
            return null;
        }
        if (!file.isDirectory()) {
            System.err.println("指定的不是目錄");
            return null;
        }
        getErgodicFiles(regex, lls, file);
        if (lls.size() == 0) {
            System.out.println("沒有找到符合的信息");
        }
        return lls;
    }

    // 遍歷文件
    public static void getErgodicFiles(String regex, LinkedList<String> lls, File file) {
        if (file.isDirectory()) {
            File[] lfs = file.listFiles();
            for (File f : lfs) {
                if (!f.isDirectory()) {
                    String absolutePath = f.getAbsolutePath();
                    if (absolutePath.matches(regex)) {
                        lls.add(absolutePath);
                    }
                } else {
                    getErgodicFiles(regex, lls, f);
                }
            }
        }
    }

    // 遍歷文件
    public static void getErgodicFiles(String fileName, File file) {
        if (file.isDirectory()) {
            File[] lfs = file.listFiles();
            for (File f : lfs) {
                if (!f.isDirectory()) {
                    f.delete();
                } else {
                    getErgodicFiles(fileName, f);
                }
            }
        }
    }

    public static void delete(String fileName) {
        File file = getFile(fileName);
        if (file == null) {
            return;
        }
        if (!file.isDirectory()) {
            file.delete();
            return;
        }
        getErgodicFiles(fileName, file);
        file.delete();
        System.out.println("刪除成功");
    }

    // 設置文件只讀,但是可以另存為
    public static void setOnlyRead(String fileName) {
        File file = getFile(fileName);
        if (file == null) {
            return;
        }
        file.setReadable(true);
        file.setWritable(false);
    }

    private static File getFile(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            System.err.println("指定的目錄或者文件夾不存在不存在");
            return null;
        }
        return file;
    }

    public static void main(String[] args) throws Exception {
        // CreateFile.creatFile("F:/test/file");
        // CreateFile.creatFolder("F:/test/file1.txt");
        // List<String> fuzzySearch = CreateFile.FuzzySearch("F:/test", "file");
        // System.out.println(fuzzySearch);
        // CreateFile.delete("F:/test/file1.txt");
        // CreateFile.setOnlyRead("F:/test/file1/file.txt");
    }
}

3.new FileOutputStream與 new RandomAccessFile的區別

一個存在則新建,一個存在則覆蓋覆蓋,默認的seek是從0開始的,RandomAccessFile對同一文件可進行讀寫

4.更改某一個文件中的值然后保存

public static void main(String[] args) {
        try {
            InputStream resourceAsStream4 = PopertiesDemo1.class.getClassLoader()
                    .getResourceAsStream("cn/collection/demo/config.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream4);
            System.out.println(properties.getProperty("name"));
            properties.setProperty("name", "李四");
            System.out.println(properties.getProperty("name"));
            FileWriter fileWriter = new FileWriter("config1");
            // "aa" 描述信息
            properties.store(fileWriter, "aa");
            fileWriter.close();
        } catch (Exception e) {
            System.out.println("沒有找到文件");
        }
    }

5.對象流

實現Externalizable接口,Externalizable繼承了Serializable 接口,Externalizable中有兩個方法需要重寫writeExternal及readExternal,在writeObject和readObject時會調用相應的方法。

transient關鍵字表示瞬態的,在保存的是是后不會被保存進對象流,假如我么依舊添加,那么可以使用如下方法

public class Person implements Serializable {
    private String adress;
    // transient 關鍵字 表示瞬態 假如需要保存這個那么需要單獨的去保存
    private transient int age;
    private static String name;
    private transient static int id;

    public String getAdress() {
        return adress;
    }

    public void setAdress(String adress) {
        this.adress = adress;
    }

    public static int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Person() {
        super();
    }

    public Person(int age, String adress, int id, String name) {
        super();
        this.age = age;
        this.adress = adress;
        this.id = id;
        this.name = name;
    }

    public static 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;
    }

    // 一定要為私有才可以被調用
    private void writeObject(ObjectOutputStream stream) throws IOException {
        // 將非靜態的非瞬態的保存在對象流中
        stream.defaultWriteObject();
        stream.writeObject(age);
        stream.close();
    }

    // 一定要為私有才可以被調用
    private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException {
     stream.defaultReadObject(); age
= (int) (stream.readObject()); stream.close(); } @Override public String toString() { return "Person [age=" + age + ", adress=" + adress + ",name=" + name + ",id=" + id + "]"; } }

6.分段讀取文件,每次只保存一部分(網絡版的在爬蟲中)

public class SegmentedReadFile extends Thread {
	private volatile boolean flag = false;
	@Override
	public void run() {
		try {
			Scanner scanner = new Scanner(System.in);
			String nextLine = scanner.nextLine();
			if (nextLine.equals("true")) {
				this.flag = true;
			}
		} catch (Exception e) {
		}
	}

	public boolean test(String src, String target) throws IOException {
		File file = new File(src);
		File file2 = new File(target);
		// 這里以單個文件為例
		if (file.isDirectory()) {
			System.out.println("該路徑是文件夾不是文件");
			return false;
		}
		if (!file.isFile()) {
			System.out.println("該文件路徑不存在");
			return false;
		}
		if (!file2.isFile()) {
			try {
				file2.createNewFile();
			} catch (IOException e) {
				return false;
			}
		}
		FileInputStream fileInputStream=null;
		BufferedInputStream bufferedInputStream=null;
		FileOutputStream fileOutputStream=null;
		BufferedOutputStream bufferedOutputStream=null;
		if (file2.isFile()) {
			long lg1 = file.length();
			int segment = 24000000;
			fileInputStream = new FileInputStream(file);
			bufferedInputStream = new BufferedInputStream(fileInputStream);
			fileOutputStream = new FileOutputStream(file2, true);
			bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
			byte[] bys = new byte[1024];
			
			if (file.length() - file2.length() >= segment) {
				long lg = file2.length();
				bufferedInputStream.skip(lg);
				for (int i = 0; i <= segment / 1024; i++) {
					if (flag) {
						break;
					}
                        bufferedInputStream.read(bys); if (i < segment / 1024 ) { bufferedOutputStream.write(bys, 0, 1024); } else { bufferedOutputStream.write(bys, 0, segment%1024); } } } else if(file.length() - file2.length()>0){ long lg = file2.length(); bufferedInputStream.skip(lg); long lastSize=file.length() - file2.length(); for (int i = 0; i <= lastSize / 1024; i++) { if (flag) { break; } int read = bufferedInputStream.read(bys); if (read != -1) { bufferedOutputStream.write(bys, 0, read); } } }else{ System.out.println("傳輸完成"); } } bufferedInputStream.close(); bufferedOutputStream.close(); System.gc(); System.runFinalization(); return true; } public static void main(String[] args) throws IOException { SegmentedReadFile segmentedReadFile = new SegmentedReadFile(); segmentedReadFile.setDaemon(true); segmentedReadFile.start(); boolean test = segmentedReadFile.test("G:/360安全瀏覽器下載安裝包/tim_pc.exe", "G:/360安全瀏覽器下載安裝包/tim_pc1.exe"); if (!test) { System.out.println("傳輸失敗"); } } }

7.重定向輸出記錄錯誤日志文件

public class Redirect1 {
   public static void main(String[] args) throws FileNotFoundException {
     String str="hello world";
     PrintStream printStream = new PrintStream("y.txt");
  //可以不關閉,自動會刷新緩存 printStream.print(str); }

8.字節字符轉換流

public static void main(String[] args) throws IOException {
         //方式一
         FileInputStream fileInputStream = new  FileInputStream("1.txt");
         //不亂碼的前提是知道編碼,或者是unicode碼的\\u方式寫的
         InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
         BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
         //java內存中是使用unicode碼保存的
         String readLine = bufferedReader.readLine();
         System.out.println(readLine);
         if(bufferedReader!=null){
             bufferedReader.close();
         }
         if(inputStreamReader!=null){
             inputStreamReader.close();
         }
         if(fileInputStream!=null){
             fileInputStream.close();
         }
         FileOutputStream fileOutputStream = new FileOutputStream("3.txt");
         OutputStreamWriter outputStreamWriter = new  OutputStreamWriter(fileOutputStream,"gbk");
         BufferedWriter bufferedWriter = new  BufferedWriter(outputStreamWriter);
         bufferedWriter.write(readLine);
         if(bufferedWriter!=null){
             bufferedWriter.close();
         }
         if(outputStreamWriter!=null){
             outputStreamWriter.close();
         }
         if(fileOutputStream!=null){
             fileOutputStream.close();
         }
         FileInputStream fileInputStream1 = new  FileInputStream("3.txt");
         //按指定解碼然后按unicode保存
         InputStreamReader inputStreamReader1 = new InputStreamReader(fileInputStream1,"gbk");
         BufferedReader bufferedReader1 = new BufferedReader(inputStreamReader1);
         String readLine1 = bufferedReader1.readLine();
        //將unicode碼有轉換成了工作空間相應的編碼
         System.out.println(readLine1);
         if(bufferedReader1!=null){
             bufferedReader1.close();
         }
         if(inputStreamReader1!=null){
             inputStreamReader1.close();
         }
         if(fileInputStream1!=null){
             fileInputStream1.close();
         }
         //方式二
         ByteArrayOutputStream byteArrayOutputStream = new  ByteArrayOutputStream();
         byteArrayOutputStream.write(readLine1.getBytes());
        //因為我的工作空間是utf-8的
         String string = byteArrayOutputStream.toString("utf-8");
         byteArrayOutputStream.close();
         System.out.println(string);
         FileInputStream fileInputStream2 = new  FileInputStream("3.txt");
         ByteArrayOutputStream byteArrayOutputStream2 = new  ByteArrayOutputStream();
         byte [] bs =new byte [1024];
         int len =0;
         while((len=fileInputStream2.read(bs))!=-1){
             byteArrayOutputStream2.write(bs, 0, len);
         }
         //不會亂碼
         String string2 = byteArrayOutputStream2.toString("gbk");
         fileInputStream2.close();
         byteArrayOutputStream2.close();
         System.out.println(string2);
         //readLine.getBytes(charset)
        //Charset.forName("UTF-8").encode(str)
   }

9.其他一些流

SequenceInputStream  合並多個流文件 SequenceInputStream(Enumeration<? extends InputStream> e)

PrintWriter 與 PrintStream 差不多

PipedWriter 是向與其它線程共用的管道中寫入數據

CharArrayWriterStringWriter 是兩種基本的介質流,它們分別向Char 數組、String 中寫入數據

DataOutputStream 保存相應的數據,按保存的順序讀取

ZipOutputStream  壓縮流   批量壓縮(文件夾)可以使用這個方法putNextEntry(ZipEntry e),ZipEntry(String name)使用指定名稱創建新的 ZIP 條目。

ZipInputStream 解壓流 

public class ZipInputStreamDemo2 {
    public static void main(String[] args) throws IOException {
        File file = new File("d:" + File.separator + "zipFile.zip");
        File outFile = null;
        ZipFile zipFile = new ZipFile(file);
        ZipInputStream zipInput = new ZipInputStream(new FileInputStream(file));
        ZipEntry entry = null;
        InputStream input = null;
        OutputStream output = null;
        while ((entry = zipInput.getNextEntry()) != null) {
            System.out.println("解壓縮" + entry.getName() + "文件");
            outFile = new File("d:" + File.separator + entry.getName());
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdir();
            }
            if (!outFile.exists()) {
                outFile.createNewFile();
            }
            input = zipFile.getInputStream(entry);
            output = new FileOutputStream(outFile);
            int temp = 0;
            while ((temp = input.read()) != -1) {
                output.write(temp);
            }
            input.close();
            output.close();
        }
    }

}
//多個文件進行壓縮
public
class ZipOutputStreamDemo2 { public static void main(String[] args) throws IOException { // 要被壓縮的文件夾 File file = new File("d:" + File.separator + "temp"); File zipFile = new File("d:" + File.separator + "zipFile.zip"); InputStream input = null; ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile)); zipOut.setComment("hello"); if (file.isDirectory()) { File[] files = file.listFiles(); for (int i = 0; i < files.length; ++i) { input = new FileInputStream(files[i]); zipOut.putNextEntry(new ZipEntry(file.getName() + File.separator + files[i].getName())); int temp = 0; while ((temp = input.read()) != -1) { zipOut.write(temp); } input.close(); } } } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM