package main

import (
	"compress/flate"
	"compress/zlib"
	"fmt"
	"io/ioutil"
	"os"
)

func main() {

	fmt.Println("-----压缩文件并且读取压缩后的数据------")
	dst_file, e := os.Create("main/zlib/zlib01_compress.txt")
	check_err_zlib(e)
	// NewWriter创建一个新的Writer。
	//压缩返回的Writer并将其写入w。
	//
	//完成后，调用方有责任在Writer上调用Close。
	//写入可能会被缓冲，直到关闭才刷新。
	//底层实现是通过：NewWriterLevelDict()方法
	//w := zlib.NewWriter(dst_file)
	//除了NewWriter之外还有：
	//zlib.NewWriterLevel()


	dict:=[]byte{'a','b','c','d','e','f'}

	// NewWriterLevelDict类似于NewWriterLevel，但指定要压缩的字典。
	//字典可能为nil。 如果没有，则在关闭Writer之前，不得修改其内容。
	w, e := zlib.NewWriterLevelDict(dst_file, flate.BestCompression, dict)// flate.BestCompression=9
	check_err_zlib(e)

	src_bytes, e := ioutil.ReadFile("main/zlib/zlib01.txt")
	check_err_zlib(e)

	n, e := w.Write(src_bytes)
	check_err_zlib(e)
	//关于w的其他方法,不再累叙：
	//	w.Flush()
	//	w.Reset()
	e = w.Close() //这个close()不能放到defer中去，因为下面要直接进行读取了，如果放到读取后才close()是无法读取正确的！
	check_err_zlib(e)
	fmt.Println("写入压缩文件的字节数是：", n)

	ret, e := dst_file.Seek(0, 0)
	check_err_zlib(e)

	fmt.Println("将压缩文件的读写指针重置到：", ret)

	// ReadAll从r读取直到出现错误或EOF，然后返回读取的数据。
	//成功的调用返回err == nil，而不是err == EOF。 因为ReadAll被定义为从src读取直到EOF，所以它不会将读取的EOF视为要报告的错误。

	dst_byte, e := ioutil.ReadAll(dst_file) //通过这个可以直接读取到，读写文件比较好用的api在这个ioutil包里面
	check_err_zlib(e)

	fmt.Println("读取到的压缩文件的字节数为：", len(dst_byte))
	fmt.Println("压缩文件的字节为：", dst_byte)
	fmt.Println("压缩文件的字符串为：", string(dst_byte))
	// 输出：
	// 	写入压缩文件的字节数是： 597
	// 	将压缩文件的读写指针重置到： 0
	// 	读取到的压缩文件的字节数为： 424
	// 	压缩文件的字节为： [120 156 92 144 95 114 218 60 20 197 223 191 153 111 145 73 186 131 110 64 128 27 254 196
	// 			49 54 1 74 44 39 20 6 166 52 19 27 147 18 42 100 27 237 37 220 35 137 39 182 208 49 120 104 167 35 189 221
	// 			123 238 239 156 115 117 125 67 242 149 196 16 60 166 60 52 161 3 223 1 47 116 116 135 238 157 109 174 41
	// 			155 219 116 170 157 238 158 213 41 27 218 201 194 204 228 49 119 117 244 138 85 231 34 164 108 254 193 34
	// 			147 41 219 126 51 253 177 94 103 199 220 53 59 143 68 129 100 3 30 127 176 39 18 146 68 118 152 142 202 209
	// 			219 14 197 15 35 127 33 104 237 89 77 183 124 253 28 145 72 205 100 176 103 245 255 255 67 180 64 206 176
	// 			29 32 239 146 232 28 115 151 68 12 94 148 63 217 144 200 32 98 218 126 179 42 192 246 39 216 4 203 28 95
	// 			86 240 93 100 210 38 187 138 28 165 198 111 32 217 124 254 116 126 224 113 9 123 118 144 73 146 210 172 50
	// 			4 133 85 254 89 74 197 195 158 213 173 122 212 163 37 9 134 72 234 97 83 143 60 146 189 67 123 109 66 167
	// 			138 199 57 229 97 233 72 53 172 226 36 111 171 202 170 229 153 126 175 149 148 52 128 106 24 46 14 44 68
	// 			207 61 107 225 183 168 136 254 161 160 197 245 48 181 247 99 235 55 74 202 247 64 119 216 133 130 213 192
	// 			120 41 201 219 138 126 154 66 246 77 127 81 46 239 60 204 11 180 239 245 227 242 84 220 223 135 237 123
	// 			106 21 183 205 23 227 108 76 232 80 241 112 120 113 255 216 23 49 102 67 155 40 36 83 211 95 64 53 180
	// 			51 70 247 171 241 150 164 158 72 120 232 6 37 156 11 146 189 115 214 61 171 145 148 36 188 243 77 244 92
	// 			155 158 202 155 57 23 47 87 215 55 191 3 0 0 255 255 199 140 166 74]
	// 	压缩文件的字符串为： x�\�_r�<�߿�o�I��n@���16J,'�4�*d�%�#�'��1xh�#��{��su}C��<�<4��/tt��m�)��t����)�����1wu
	// 	�U�"�l��"�)�~3��^g��5;�D�d�'�Dv������#!h�YM�|��H�d�g���C�@ΰ ��s�D^�?ِ� b�~�*��'��_V�]d�&����o �|�t~�q	{v
	// 	�I�Ҭ2�U�YJ�Þխzԣ%	�H�aS�<��C{mB���9�a�H5��$o�ʪ�~���4�j.,D�=kᷨ������0��c�7J��@w؅���x)�ۊ~�B�MQ.�<������T�߇�{j���l
	// 	L�P�pxq��1fC�($S�_@5�3F��񖤞Hx�%���s�=���$��M�\��ʛ9/W�7�
	fmt.Println()
	fmt.Println("-------解压并且读取出来---------")

	ret1, e := dst_file.Seek(0, 0)
	check_err_zlib(e)

	fmt.Println("将压缩文件的读写指针重置到：", ret1)

	//ReadCloser, e := zlib.NewReader(dst_file)//无字典时候可以用，有字典时候无法解压了
	ReadCloser, e := zlib.NewReaderDict(dst_file,dict)
	//ReadCloser, e := zlib.NewReaderDict(dst_file,[]byte{'a','b','c','d','e'})//字典必须跟压缩时候的字典一致才能正常的解压
	read_dst_byte := make([]byte, len(src_bytes))
	n2, e := ReadCloser.Read(read_dst_byte)

	fmt.Println("解压后的数据的字节数是：", n2)
	fmt.Println("解压后的字节是：", read_dst_byte)
	fmt.Println("解压后的字符串是：", string(read_dst_byte))
	ReadCloser.Close()
	//输出：
	//	-------解压并且读取出来---------
	//	将压缩文件的读写指针重置到： 0
	//	解压后的数据的字节数是： 597
	//	解压后的字节是： [97 98 99 228 186 172 228 184 150 229 155 173 228 188 154 231 154 132 229 144 132 229 155 189 230 156 139 229 143
	//		139 232 135 180 228 187 165 232 176 162 230 132 143 227 128 130 228 187 150 232 161 168 231 164 186 239 188 140 230 156 172 229 177
	//		138 228 184 150 229 155 173 228 188 154 228 187 165 226 128 156 231 187 191 232 137 178 231 148 159 230 180 187 239 188 140 231 190
	//		142 228 184 189 229 174 182 229 155 173 226 128 157 228 184 186 228 184 187 233 162 152 239 188 140 231 178 190 229 189 169 231 186
	//		183 229 145 136 227 128 129 230 136 144 230 158 156 228 184 176 231 161 149 227 128 130 13 10 229 156 168 229 188 128 229 185 149 229
	//		188 143 228 184 138 239 188 140 228 184 173 229 155 189 229 155 189 229 174 182 228 184 187 229 184 173 228 185 160 232 191 145 229
	//		185 179 229 128 161 229 175 188 229 133 177 229 144 140 229 187 186 232 174 190 231 190 142 228 184 189 229 156 176 231 144 131 229
	//		174 182 115 100 115 100 115 100 115 100 229 155 173 227 128 129 230 158 132 229 187 186 228 186 186 231 177 187 229 145 189 232 191
	//		144 229 133 177 229 144 140 228 189 147 227 128 130 232 191 153 230 152 175 228 184 128 229 156 186 230 150 135 230 152 142 228 186
	//		146 233 137 180 231 154 132 231 187 191 232 137 178 231 155 155 228 188 154 239 188 140 228 191 131 232 191 155 228 186 134 229 144
	//		132 229 155 189 230 150 135 230 152 142 228 186 164 230 181 129 227 128 129 230 176 145 229 191 131 231 155 184 233 128 154 229 146
	//		140 231 187 191 232 137 178 229 144 136 228 189 156 227 128 130 232 191 153 230 152 175 228 184 128 229 156 186 229 136 155 230 150
	//		176 232 141 159 232 144 131 231 154 132 231 167 145 230 138 128 231 155 155 228 188 154 239 188 140 229 177 149 231 142 176 228 186
	//		134 231 187 191 232 137 178 231 167 145 230 138 128 229 186 148 231 148 168 231 154 132 231 190 142 229 165 189 229 137 141 230 153
	//		175 227 128 130 13 10 232 191 153 230 152 175 228 184 128 229 156 186 232 181 176 232 191 155 232 135 170 231 132 182 231 154 132 228
	//		189 147 233 170 140 231 155 155 228 188 154 239 188 140 228 184 173 229 164 150 232 174 191 229 174 162 231 148 168 229 191 131 230 132
	//		159 229 143 151 231 142 175 228 191 157 228 184 142 229 143 145 229 177 149 231 155 184 228 186 146 228 191 131 232 191 155 227 128 129
	//		228 186 186 228 184 142 232 135 170 231 132 182 229 146 140 232 176 144 229 133 177 229 164 132 231 154 132 231 190 142 229 165 189 97 98 99]
	//	解压后的字符串是： abc京世园会的各国朋友致以谢意。他表示，本届世园会以“绿色生活，美丽家园”为主题，精彩纷呈、成果丰硕。
	//	在开幕式上，中国国家主席习近平倡导共同建设美丽地球家sdsdsdsd园、构建人类命运共同体。这是一场文明互鉴的绿色盛会，促进了各国文明交流、民心相通和绿色合作。这是一场创新荟萃的科技盛会，展现了绿色科技应用的美好前景。
	//	这是一场走进自然的体验盛会，中外访客用心感受环保与发展相互促进、人与自然和谐共处的美好abc
}
func check_err_zlib(err error) {

	if err != nil {
		fmt.Println(err)
	}
}
