Home  >  Article  >  Java  >  How to use character stream to read and write non-text files in Java

How to use character stream to read and write non-text files in Java

王林
王林forward
2023-04-18 19:04:041121browse

    Use character stream to read files (non-text)

    Take Java's character stream to read files as an example: it can only read For characters between 0-65535, it can be seen that the characters are all positive numbers, but the binary byte can be negative numbers. But when reading, it will be read as a positive number, or a character that cannot be found in the encoding table will return a strange symbol (you may have seen that strange "?").

    But in some cases, characters must be used to display binary data, and there is no way. Let’s introduce one of our methods -base64 encoding .

    Base64 encoding

    Introduction to base64 encoding

    base64 is one of the common encoding methods used to transmit 8Bit bytecode on the Internet. Base64 is a coding method based on A method of representing binary data with 64 printable characters. Base64 encoding is a process from binary to characters and can be used to transmit longer identification information in an HTTP environment. Base64 encoding is unreadable and needs to be decoded before it can be read. Its Chinese name is based on 64 printable characters to represent binary data.

    Encoding rules

    1. Convert 3 bytes into 4 bytes.

    2. No 76 characters plus a newline character.

    3. The final terminator must also be processed.

    Disadvantages of the encoding method

    As can be seen from the encoding rules, base64 requires that every three 8Bit bytes be converted into four 6Bit characters (38 = 46 = 24) , and then add two high-bit 0s to the 6Bit to form four 8Bit bytes. In other words, the converted string will theoretically be 1/3 (33%) longer than the original one.

    Here is an introduction to a concept and more detailed content. If you are interested, you can collect it to learn more.

    Application of Base64 in Java

    Java's Base64 tool class provides a set of static methods to obtain the following three BASE64 codecs:

    • Basic: The output is mapped to a set of characters A-Za-z0-9/, encoding does not add any line markers, and decoding of the output only supports A-Za-z0-9/.

    • URL: The output maps to a set of characters A-Za-z0-9 _, the output is a URL and a file.

    • MIME: Output is implicitly mapped to a MIME friendly format. The output should be no longer than 76 characters per line and separated by '\r' followed by '\n'. The encoded output ends up with no line splitting.

    corresponds to the following methods:

    Encoder basicEncoder = Base64.getEncoder();
    Encoder mimeEncoder = Base64.getMimeEncoder();
    Encoder urlEncoder = Base64.getUrlEncoder();

    I wrote a simple tool class to testBasic(basic) encoder . .

    package com.dragon;
    
    import java.io.BufferedInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.util.Base64;
    import java.util.Base64.Decoder;
    import java.util.Base64.Encoder;
    
    /**
     * @author Alfred
     * */
    public class Base64Util {
    	private static Encoder encoder = Base64.getEncoder();
    	private static Decoder decoder = Base64.getDecoder();
    	private static String ENCODE = "UTF-8";
    	private static int LENGTH = 1024;
    	
    	/**
    	 * 静态方法:
    	 * 将文件等二进制数据(文本和非文本都可以)
    	 * 转为base64字符串。
    	 * @throws IOException 
    	 * @throws FileNotFoundException 
    	 * 
    	 * */
    	public static String dataToBase64(File src) throws FileNotFoundException, IOException {
    		Encoder encoder = Base64.getEncoder();
    		
    		int len = (int)src.length();
    		byte[] bar = new byte[(int)len];
    		int hasRead = 0;
    		byte[] b = new byte[LENGTH];
    		//使用专门处理 byte 的IO流比较方便,一次性读取较大文件对内存压力较大
    		try (InputStream in = new BufferedInputStream(new FileInputStream(src));
    				ByteArrayOutputStream bos = new ByteArrayOutputStream(len)) {
    			while ((hasRead = in.read(b)) != -1) {
    				bos.write(b, 0, hasRead);
    			}
    			bar = bos.toByteArray();
    		}
    		return encoder.encodeToString(bar);
    	}
    	
    	public static String dataToBase64(String src) throws UnsupportedEncodingException {
    		return encoder.encodeToString(src.getBytes(ENCODE));
    	}
    	
    	public static byte[] base64ToData(String src) {
    		return decoder.decode(src);
    	}
    }

    Convert the image to Base64 string for reading and writing

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.io.Writer;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Base64Test {
    	public static void main(String[] args) throws FileNotFoundException, IOException {
    		testPic();
    	}
    	
    	static void testPic() throws FileNotFoundException, IOException {
    		// 测试图片文件。
    		Path picPath = Paths.get("./src/com/dragon/001.jpg");
    		File picFile = picPath.toFile();
    		String picToBase64 = Base64Util.dataToBase64(picFile);
    		System.out.println(picToBase64);
    		long oldSize = picFile.length();
    		long newSize = picToBase64.getBytes("UTF-8").length;
    		System.out.println("图片原始大小(字节):" + oldSize);
    		System.out.println("转换后数据大小(字节):" + newSize);
    		System.out.println("转换后比原来扩大的比例为:" + (double)(newSize-oldSize)/(double)oldSize + " %");
    		
    		//将数据写入文件
    		try (Writer writer = new BufferedWriter(new FileWriter("./src/com/dragon/002.txt"))) {
    			writer.write(picToBase64);
    		}
    		
    		//从文件中读取数据
    		String line = null;
    		try (BufferedReader reader = new BufferedReader(new FileReader("./src/com/dragon/002.txt"))){
    			line = reader.readLine();
    		}
    		System.out.println(picToBase64.equals(line));
    	}
    }

    Run screenshot

    How to use character stream to read and write non-text files in Java

    ##Instructions: Here After converting the image to a base64 string, use the character stream to write a text file, then use the character stream to read it out, and then compare it with the original string and the result is true.

    So, the reading of the image data is completed. Maybe you said here that you are not reading the binary data of the image, but in fact, all files are stored in binary! Moreover, this base64 string can also be used directly as an image.

    Note: I have selected a very small picture here. You can see that the original size is only 3639 bytes, which is less than 4 KB, but if it is converted into text, it will be a lot (

    So, it will appear very long, very long. ).

    Test picture

    How to use character stream to read and write non-text files in Java

    #Then you may ask how to prove that this string is the above picture? This is also easy to do. If you know something about the front-end, you should know that the front-end pictures can be represented by base64 strings. Let’s write an html file to test it.

    image.html

    <!DOCTYPE>
    <html>
        <head>
            <meta charset="UTF-8"/>
            <title>base测试</title>
        </head>
        <body>
            <img src="data:image/jpeg;base64,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"/>
        </body>
    <html>

    Open the browser to test it

    How to use character stream to read and write non-text files in Java

    Instructions: Its specific usage is as follows:

    1cff3a8f13d8e2ea6f7ab73fd6a0d943

    of the picture The size is actually quite huge compared to the characters. The html code I have here is the base64 encoded string of the complete image, and then the word count of my blog becomes much larger.

    Convert string to base64 encoding

    public class Base64Test {
    	public static void main(String[] args) throws FileNotFoundException, IOException {
    		testStr("I love you yesterday and today!");
    	}
    	
    	static void testStr(String src) throws UnsupportedEncodingException {
    		//测试文本数据。
    		String strToBase64 = Base64Util.dataToBase64(src);
    		System.out.println("base64编码:" + strToBase64);
    		String base64ToStr = new String(Base64Util.base64ToData(strToBase64));
    		System.out.println("base64解码:" + base64ToStr);
    	}
    }

    Test screenshot

    How to use character stream to read and write non-text files in Java

    Use of base64

    Base64 is often used to represent, transmit, and store some binary data in situations where text data is usually processed. Including MIME email, email via MIME, storing complex data in XML. Note 1: There are also many websites on the Internet that can perform encoding and decoding. If you need to use it, you can give it a try.

    注2:可以观察一下这个base64字符串的特点,我上次学习Java爬虫的时候,爬了一个网站,发现这个网站的一个 script 脚本中,含有一个json对象,其中有一个属性是 url,但是对应的链接却看不懂(base64字符串是不可读的),但是我感觉它就是base64字符串,所以我利用base64编解码网站解码一看,真的是一个网站的地址。然后,就可以写一个解码方法,当爬到这个数据时,给它解码了,哈哈。

    举一个简单的例子:

    {"url":"aHR0cHMlM0ElMkYlMkZ3d3cuYmFpZHUuY29tJTJG"}
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    import java.util.Base64;
    import java.util.Base64.Decoder;
    import java.util.Base64.Encoder;
    
    public class TestALittle {
    	public static void main(String[] args) throws UnsupportedEncodingException {
    		String base64Str = "aHR0cHMlM0ElMkYlMkZ3d3cuYmFpZHUuY29tJTJG";
    		String de_str = base64ToUrlEncoderToURL(base64Str);
    		System.out.println("解码:" + de_str);
    	}
    	
    	//base64解密为urlencoder,再解码为url
    	public static String base64ToUrlEncoderToURL(String base64Str) throws UnsupportedEncodingException {
    		Decoder decoder = Base64.getDecoder();
    		byte[] bt = decoder.decode(base64Str);
    		String en_str = new String(bt, 0, bt.length);
    		return URLDecoder.decode(en_str, "UTF-8");
    	}
    }

    How to use character stream to read and write non-text files in Java

    说明: 这个例子中的 url 进行了两次编码,第一次是将url中的非西欧字符编码(可以去了解一下为什么这么做?),然后再使用base64编码。但是,如果你掌握了解码技术,解码也是很简单的。(但是如果你看不出来它是base64编码,那估计就没有办法了!)

    The above is the detailed content of How to use character stream to read and write non-text files in Java. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete
    Previous article:How to apply CAS in javaNext article:How to apply CAS in java