各种语言【Python,Java,Go,Pascal,C++】不解压直接读取压缩包【rar,zip,7z,gz,tar,z...】中文本行

文章目录

  • (零)前言
  • (一)【ZIP】格式
    • (1.1)Python ⭐️
    • (1.2)Java ⭐️
    • (1.3)Golang ⭐️
    • (1.4)Pascal
      • (1.4.1)Lazarus(Free Pascal)
      • (1.4.2)Delphi ⭐️
    • (1.5)C++
  • (二)【GZIP】格式
    • (2.1)Python ⭐️
    • (2.2)Java ⭐️
    • (2.3)Golang ⭐️
    • (2.4)Pascal
      • (2.4.1)Lazarus(Free Pascal)
      • (2.4.2)Delphi ⭐️
    • (2.5)C++ ⭐️
  • (三)【TAR】格式
    • (3.1)Python ⭐️
    • (3.2)Java ⭐️
    • (3.3)Golang ⭐️
    • (3.4)Pascal
      • (3.4.1)Lazarus(Free Pascal)
      • (3.4.2)Delphi ⭐️
  • (四)【RAR】格式
    • (4.1)Python
    • (4.2)Java
    • (4.3)Golang ⭐️
  • (五)【7Zip】格式
    • (5.1)Python ⭐️
    • (5.2)Java ⭐️
    • (5.3)Golang ⭐️
  • (六)【Unix Z】格式
    • (6.1)Python ⭐️
    • (6.2)Java ⭐️
    • (6.3)Golang ⭐️

(零)前言

通常的情况下遇到压缩包,都是解开后再进行文件操作。
比如把A.zip 解压缩成-> a.txt,再用程序打开a.txt正常读取。
上网查各种例子也是文件解开到文件。

很多年前我们也是这么干的,直到发现了这些情况:

  1. 似乎是4G时代吧,VoLTE的时代,各个厂商都用极其冗长的格式来存储并传输数据。
    导致压缩比非常大比如大到100:1。也就是1GB的压缩包,解开后是100GB的数据。
    这些无谓的磁盘开销改为直接读取压缩包就可以完全避免。

  2. 服务器虚拟化后,有些磁盘读写(尤其是写)特别慢。
    比如200MB的数据如果解压成4GB再进行处理,单个数据节点需要4小时,不解压只要2分钟左右。
    时间的差距实在是巨大。

所以不得已,只能直接读写压缩文件了。
不能调用外部的命令,还得兼顾跨平台,各种语言实现的方式都不太一样。
能读通常就能写,加上读文本比读二进制块更“高级”,所以就用读文本做例子吧。

带有⭐️的例子,能够完成“直接读文本行”的功能,其它例子得自己改。

(一)【ZIP】格式

是Windows下最常见的格式。
单个压缩包内可以包含多个文件
虽然压缩率不及RAR和7Z,读取速度不及GZIP,但是在Windows下兼容性是最好的。
常见的软件:WinZip。

(1.1)Python ⭐️

我完全不懂python,不过挺好用呢。
对zip的支持是自带的。
参考:🔗Python的数据压缩与存档。

import zipfile
...
if not zipfile.is_zipfile(SourceFile):raise Exception(SourceFile+" is not in ZIP format!")
with zipfile.ZipFile(SourceFile) as zipMy:for oneItem in zipMy.infolist():with zipMy.open(oneItem) as filein:lines = filein.readlines()# do what ever with lines.

(1.2)Java ⭐️

看上去Java是流式处理。
如果某文件被zip重复压缩了几次,用Java也可以一次读出最内层的数据(理论如此,没试过)。
org.apache.commons.compress

pom.xml中添加依赖:

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.24.0</version>
</dependency>

.java代码文件中:

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
...try(ZipFile zipFile =  new ZipFile(SourceFile, "GBK")){Enumeration<?> enums = zipFile.getEntries();while(enums.hasMoreElements()){ZipArchiveEntry entry = (ZipArchiveEntry) enums.nextElement();if(!entry.isDirectory()){try(BufferedReader br = new BufferedReader(new InputStreamReader(zipFile.getInputStream(entry), Charset.forName("GBK")))){String aLine;while((aLine=br.readLine()) != null) {// do what ever with every Line.}}}}
}

(1.3)Golang ⭐️

同上,发现Go的Reader也能流式处理。
本身代码没几行,但是error处理占了不少代码。
还有defer close,显然没有Python的with简练,也比不过Java的try with resource,哎这也是Go的一大特点。

import (..."archive/zip"...
)
...zipReader, err := zip.OpenReader(SourceFile)
if err != nil {panic(err)
}
defer func(zipReader *zip.ReadCloser) {err := zipReader.Close()if err != nil {panic(err)}
}(zipReader)
for _, f := range zipReader.File {if !f.FileInfo().IsDir() {inFile, err := f.Open()if err != nil {panic(err)}OneReader := bufio.NewReader(inFile)for {line, _, err := OneReader.ReadLine()if err == io.EOF {MyEof = truebreak}if err != nil {panic(err)}// do what ever with every Line.}}
}

(1.4)Pascal

(1.4.1)Lazarus(Free Pascal)

在Lazarus(FPC)官方WIKI关于paszlib中有接近的方式:

  1. 不设置TUnZipper的OutputPath。
  2. 在事件中创建和读取Stream。
  3. 我们可以用自己的Steam来取得其中内容,再按行读取(虽然曲折,也算间接实现了吧)。

FPC官方相关的代码如下(稍改就行):

usesZipper;...procedure TForm1.Button1Click(Sender: TObject);
beginExtractFileFromZip(FileNameEdit1.FileName,Edit1.Text);
end;procedure TForm1.DoCreateOutZipStream(Sender: TObject; var AStream: TStream;AItem: TFullZipFileEntry);
beginAStream:=TMemorystream.Create;
end;procedure TForm1.DoDoneOutZipStream(Sender: TObject; var AStream: TStream;AItem: TFullZipFileEntry);
beginAStream.Position:=0;Memo1.lines.LoadFromStream(Astream);Astream.Free;
end;procedure TForm1.ExtractFileFromZip(ZipName, FileName: string);
varZipFile: TUnZipper;sl:TStringList;
beginsl:=TStringList.Create;sl.Add(FileName);ZipFile := TUnZipper.Create;tryZipFile.FileName := ZipName;ZipFile.OnCreateStream := @DoCreateOutZipStream;ZipFile.OnDoneStream:=@DoDoneOutZipStream;ZipFile.UnZipFiles(sl);finallyZipFile.Free;sl.Free;end;
end;

(1.4.2)Delphi ⭐️

新版Delphi可以这样:

usesSystem.Zip,...
varline:String;aLH:TZipHeader...
begin	LZip:=TZipFile.Create;LZip.Open(SourceFile,zmRead);LZip.Encoding:=TEncoding.GetEncoding(936);for i:=0 to LZip.FileCount-1 dobeginLOutput := TMemoryStream.Create();LZip.Read(i,LOutput,aLH);var asr:=TStreamReader.Create(LOutput);while not asr.EndOfStream dobeginline:String;line:=asr.ReadLine;// do what ever with every Line.end;FreeAndNil(asr);FreeAndNil(LOutput);end;FreeAndNil(LZip);
end;

(1.5)C++

使用zlib。下面的例子用的是zlib1.3(August 18, 2023)

如果是从实际的zip文件来处理,似乎可以这样。
PS:同样是zlib提供的,gz可以按行读取(见下面gz的部分),而zip只能读数据块。
⚠️按行读字符串需要再判断一下\n的位置啥的,自己组成字符串。。

unzFile zfile = unzOpen64(SourceFile);
unz_global_info64 globalInfo;
if (UNZ_OK != unzGoToFirstFile(zfile))
{return false;
}char fileName[512] = { 0 };
unz_file_info64 fileInfo;
do
{if (UNZ_OK != unzGetCurrentFileInfo64(zfile, &fileInfo, fileName, sizeof(fileName), nullptr, 0, nullptr, 0)){return false;}if (fileInfo.external_fa == FILE_ATTRIBUTE_DIRECTORY)	// 文件夹{//如果需要处理,就自己建目录啊。}else	// 普通文件{if (UNZ_OK != unzOpenCurrentFile(zfile)){return false;}int size = 0;while (unzReadCurrentFile(zfile, Buffer, bufferSize) != NULL){//do what ever with Buffer}}
} while (unzGoToNextFile(zfile) != UNZ_END_OF_LIST_OF_FILE);
unzClose(zfile);

(二)【GZIP】格式

是Linux/Unix下最常见的压缩格式。
单个压缩包内只能包含单个文件

  • 可以保存压缩前的原始文件名的信息到meta data里。
  • 也可以不保存(去掉.gz后缀就是原始文件名)。

(2.1)Python ⭐️

对gz的支持是自带,不用额外安装包。
根本和打开文件文件没区别。
似乎读不到Meda data中的原始文件名。

import gzip
...
with gzip.open(SourceFile,'r') as gzMy:lines=gzMy.readlines()# do what ever with lines.

(2.2)Java ⭐️

可以用GzipCompressorInputStream.getMetaData().getFilename()读取原始文件名(没存就为空)。

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.24.0</version>
</dependency>
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
...try(BufferedReader br = new BufferedReader(new InputStreamReader(new GzipCompressorInputStream(Files.newInputStream(Paths.get(SourceFile))), Charset.forName("GBK"))))
{String aLine;while((aLine=br.readLine()) != null) {// do what ever with every Line.}
}

(2.3)Golang ⭐️

可以从*gzip.Reader.Name中读取原始文件名(没存就为空)。

import (..."compress/gzip"...
)
...fz, err := gzip.NewReader(SourceFile)
if err != nil {panic(err)
}
defer func(fz *gzip.Reader) {err := fz.Close()if err != nil {panic(err)}
}(fz)
OneReader := bufio.NewReader(fz)
for {line, _, err := OneReader.ReadLine()if err == io.EOF {MyEof = truebreak}if err != nil {panic(err)}// do what ever with every Line.
}

(2.4)Pascal

(2.4.1)Lazarus(Free Pascal)

也是官方的例子,似乎没有读一行的方式。
不过改改也能用是吧(下面是张图片,代码请参考官方文档)。
code

(2.4.2)Delphi ⭐️

新版Delphi可以这样:

usesSystem.ZLib,...
varline:String;...
begin	LInput := TFileStream.Create(SourceFile, fmOpenRead);LUnGZ := TZDecompressionStream.Create(LInput,15 + 16);var asr:=TStreamReader.Create(LUnGZ);while not asr.EndOfStream dobeginline:String;line:=asr.ReadLine;// do what ever with every Line.end;FreeAndNil(asr);FreeAndNil(LUnGZ);FreeAndNil(LInput);
end;

(2.5)C++ ⭐️

使用zlib。下面的例子用的是zlib1.3(August 18, 2023)

如果是从实际的gz文件来处理,似乎可以这样。
PS:严谨些需要判断读到的内容长度是否为bufferSize-1(没到换行符呢),自己再处理一下。

gzFile gzf = gzopen(SourceFile, "r");
while (gzgets(gzf, Buffer, bufferSize)!=NULL)
{//do what ever with Buffer as char*
}
gzclose(gzf);

但如果来自流,比如下面的InputStream,那么代码就有点长了。

⚠️下面的代码没有提供readline这种方便的方式。
需要自己把解开的outBuffer复制到自己的缓存中,再判断一下\n的位置啥的,自己组成字符串。
如果还需要自由的fseek移动位置,那么还是全部写入内存流当中再操作比较好。

供参考(改改才能用):

z_stream zlibStream;
memset(&zlibStream, 0, sizeof(zlibStream));
zlibStream.next_in = nullptr;
zlibStream.avail_in = 0;
zlibStream.next_out = nullptr;
zlibStream.avail_out = 0;
zlibStream.zalloc = Z_NULL;
zlibStream.zfree = Z_NULL;
zlibStream.opaque = Z_NULL;if (inflateInit2(&zlibStream, 16 + MAX_WBITS) != Z_OK) {// show errorif (error_list_.end() == error_list_.find(path)){error_list_[path] = 0x00;}error_list_[path] |= 0x04;continue;
}char* inBuffer = new char[bufferSize];
char* outBuffer = new char[bufferSize];int zlibResult;
do {InputStream.read(inBuffer, bufferSize);zlibStream.next_in = reinterpret_cast<Bytef*>(inBuffer);zlibStream.avail_in = (uInt)InputStream.gcount();do {zlibStream.next_out = reinterpret_cast<Bytef*>(outBuffer);zlibStream.avail_out = bufferSize;zlibResult = inflate(&zlibStream, Z_NO_FLUSH);if (zlibResult == Z_STREAM_ERROR) {// show errorinflateEnd(&zlibStream);if (error_list_.end() == error_list_.find(path)){error_list_[path] = 0x00;}error_list_[path] |= 0x04;continue;}//Do something with decompressed data, write to some file? //OutputStream.write(outBuffer, bufferSize - zlibStream.avail_out);} while (zlibStream.avail_out == 0);
} while (InputStream.good() || zlibResult == Z_OK);delete[] inBuffer;
delete[] outBuffer;inflateEnd(&zlibStream);
OriginalFile.flush();
OriginalFile.close();

(三)【TAR】格式

是Linux/Unix下最常见的打包格式。
单个压缩包内可以包含多个文件
打包通常和压缩同时使用,比如:.tar.gz.tgz.tar.xz

(3.1)Python ⭐️

对tar的支持是自带,不用额外安装包。
下面例子是.tar.gz.tgz的,其它的格式类似。
Python不用依次串起来解gz和解tar。只需要指定open时的参数。
可以从TarInfo.name得到包中每个文件的名字。

import tarfile
...
with tarfile.open(SourceFile,'r:gz') as tarMy:for oneItem in tarMy.getmembers():with tarMy.extractfile(oneItem) as filein:lines = filein.readlines()# do what ever with lines.

(3.2)Java ⭐️

同上例子是单独的.tar
可以从org.apache.tools.tar.TarEntry.getName()得到包中每个文件的名字。

<!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
<dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.10.14</version>
</dependency>
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;
...try (TarInputStream in = new TarInputStream(Files.newInputStream(new File(SourceFile).toPath()),"UTF8")) {TarEntry entry;while ((entry = in.getNextEntry()) != null) {if (entry.isFile()) {try(BufferedReader br = new BufferedReader(new InputStreamReader(in, Charset.forName("GBK")))){String aLine;while((aLine=br.readLine()) != null) {// do what ever with every Line.}}}}
}

(3.3)Golang ⭐️

同上例子是单独的.tar文件。
如果是tar.gz则和解gz串起来就好了。
类似:OneTAR := tar.NewReader(GZReader)这样。
可以从*tar.Header.FileInfo().Name()得到包中每个文件的名字。

import (..."archive/tar"...
)
...OneTAR := tar.NewReader(SourceFile)
for {h, err := OneTAR.Next()if err == io.EOF {break} else if err != nil {panic(err)}if !h.FileInfo().IsDir() {OneReader := bufio.NewReader(OneTAR)for {line, _, err := OneReader.ReadLine()if err == io.EOF {MyEof = truebreak}if err != nil {panic(err)}// do what ever with every Line.}}
}

(3.4)Pascal

(3.4.1)Lazarus(Free Pascal)

请参考官方文档。

(3.4.2)Delphi ⭐️

新版Delphi可以这样:
需要LibTar(Tar Library),也许还有其它实现方式,不太清楚。
同上例子是单独的.tar文件。
如果是tar.gz则和解gz串起来就好了。

usesLibTar,...
varline:String;DirRec:TTarDirRec;...
beginLInput := TFileStream.Create(SourceFile, fmOpenRead);TarStream:= TTarArchive.Create(LInput);TarStream.Reset;while TarStream.FindNext(DirRec) dobeginLOutput := TMemoryStream.Create();TarStream.ReadFile(LOutput);var asr:=TStreamReader.Create(LOutput);while not asr.EndOfStream dobeginline:String;line:=asr.ReadLine;// do what ever with every Line.end;FreeAndNil(asr);FreeAndNil(LOutput);end;FreeAndNil(TarStream);FreeAndNil(LInput);
end;

(四)【RAR】格式

是Windows下主流的压缩格式。
单个压缩包内可以包含多个文件
压缩比较高,最新的是RAR5格式。
常见的软件:🔗WinRAR。

(4.1)Python

需要pip install rarfile
用法和zip基本没区别,实测没成功,需要调用unrar.exe什么的。
此项暂时保留(参考zipfile的方式真的几乎一样)。

(4.2)Java

com.github.junrar不能处理RAR5格式.
net.sf.sevenzipjbinding可以处理RAR5,但直接用只能read数据块。

  • 用这种方法不仅可以读RAR,还可以解压非常多的格式,包括7Z,ZIP,TAR,GZ,ARJ,CAB,WIM,etc……💡
    如果仅仅需要解压成文件,那么单这一种方式就可以处理常见的所有压缩格式啦。

  • 下面取得文件名那部分和解压RAR无关,主要是gz格式有取不到文件名的情况(no metadata)。

  • 修改pom中的依赖为sevenzipjbinding-all-platforms,支持更多的平台(MAC,ARM……)💡。

<!-- https://mvnrepository.com/artifact/net.sf.sevenzipjbinding/sevenzipjbinding -->
<dependency><groupId>net.sf.sevenzipjbinding</groupId><artifactId>sevenzipjbinding</artifactId><version>16.02-2.01</version>
</dependency><!-- https://mvnrepository.com/artifact/net.sf.sevenzipjbinding/sevenzipjbinding-windows-amd64 -->
<dependency><groupId>net.sf.sevenzipjbinding</groupId><artifactId>sevenzipjbinding-windows-amd64</artifactId><version>16.02-2.01</version>
</dependency><!-- https://mvnrepository.com/artifact/net.sf.sevenzipjbinding/sevenzipjbinding-linux-amd64 -->
<dependency><groupId>net.sf.sevenzipjbinding</groupId><artifactId>sevenzipjbinding-linux-amd64</artifactId><version>16.02-2.01</version>
</dependency>

代码中的SevenZip.openInArchive(null...为啥用null,是为了自动检测格式。
顺便吐槽匿名函数,不熟悉看不懂在干嘛。
实际上是在处理ISequentialOutStream->write(byte[] data)

import actp.tnu.api.CrossLog;
import net.sf.sevenzipjbinding.ExtractOperationResult;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
...public static void Uncompress(File inputFile, String targetFileDir) throws Exception {File newdir = new File(targetFileDir);if (!newdir.exists() && !newdir.mkdirs()) {throw new Exception("Create Dir failed! : " + targetFileDir);}try (RandomAccessFile randomAccessFile = new RandomAccessFile(inputFile, "r");IInArchive inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile))) {ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {if (!item.isFolder()) {ExtractOperationResult result = item.extractSlow(data -> {try {String fileName = GetNameAndPathOK(inputFile, targetFileDir, item);try (FileOutputStream fos = new FileOutputStream(targetFileDir + File.separator + fileName, true)) {fos.write(data);//change sth here, if you want to read line}} catch (Exception e) {throw new SevenZipException(e.getMessage());}return data.length;});if (result != ExtractOperationResult.OK) {//error}}}}
}private static String GetNameAndPathOK(File inputFile, String targetFileDir, ISimpleInArchiveItem item) throws Exception {String fileName = item.getPath();if (fileName == null || fileName.isEmpty()) {fileName = inputFile.getName().substring(0, inputFile.getName().lastIndexOf("."));}if (fileName.indexOf(File.separator) > 0) {String path = targetFileDir + File.separator + fileName.substring(0, fileName.lastIndexOf(File.separator));File newdir1 = new File(path);if (!newdir1.exists() && !newdir1.mkdirs()) {throw new Exception("Create Dir failed! : " + path);}}return fileName;
}

(4.3)Golang ⭐️

使用github.com/nwaples/rardecode
也有其它的方式处理RAR,比如archiver.NewRar().Unarchive(Source,Dest)是从文件解压到文件,但不能直接读压缩包的内容。

import (..."github.com/nwaples/rardecode"...
)
...RARReader, err := rardecode.OpenReader(SourceFile, "")
if err != nil {panic(err)
}
defer func(RARReader *rardecode.ReadCloser) {err := RARReader.Close()if err != nil {panic(err)}
}(RARReader)for {f, err := RARReader.Next()if err != nil {break}if !f.IsDir {OneReader := bufio.NewReader(RARReader)for {line, _, err := OneReader.ReadLine()if err == io.EOF {MyEof = truebreak}if err != nil {panic(err)}// do what ever with every Line.}}
}

(五)【7Zip】格式

是Windows下新晋的压缩格式,扩展名.7z
单个压缩包内可以包含多个文件
压缩比较高,处理速度较快。
常用的软件:🔗7Zip。不过我比较喜欢基于它的:🔗NanaZip。
💡Nana = なな = 七。

(5.1)Python ⭐️

需要安装包:pip install py7zr

import py7zr
...
if not py7zr.is_7zfile(SourceFile):raise Exception(SourceFile+" is not in 7Z format!")
with py7zr.SevenZipFile(SourceFile) as sevenMy:for oneItem in sevenMy.files:filein = sevenMy.read([oneItem.filename])lines = filein[oneItem.filename].readlines()# do what ever with lines.

(5.2)Java ⭐️

org.apache.commons.compress

 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.24.0</version></dependency>
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
...try (SevenZFile z7In = new SevenZFile(SourceFile)){SevenZArchiveEntry entry;while ((entry = z7In.getNextEntry()) != null) {if (!entry.isDirectory()) {try(BufferedReader br = new BufferedReader(new InputStreamReader(z7In.getInputStream(entry), Charset.forName("GBK")))){String aLine;while((aLine=br.readLine()) != null) {// do what ever with every Line.}}}}
}

(5.3)Golang ⭐️

使用github.com/bodgit/sevenzip

import (..."github.com/bodgit/sevenzip"...
)
...sevenReader, err := sevenzip.OpenReader(SourceFile)
if err != nil {panic(err)
}
defer func(sevenReader *sevenzip.ReadCloser) {err := sevenReader.Close()if err != nil {panic(err)}
}(sevenReader)
for _, f := range sevenReader.File {if !f.FileInfo().IsDir() {inFile, err := f.Open()if err != nil {panic(err)}OneReader := bufio.NewReader(inFile)for {line, _, err := OneReader.ReadLine()if err == io.EOF {MyEof = truebreak}if err != nil {panic(err)}// do what ever with every Line.}}
}

(六)【Unix Z】格式

是Linux/Unix下古老的压缩格式,扩展名.z
单个压缩包内只能包含单个文件

  • 和gzip不同,Unix Z格式似乎不能保存原始文件名(去掉.z后缀就是原始文件名)。

(6.1)Python ⭐️

需要pip install unlzw3

import unlzw3
...unCompress = BytesIO(unlzw3.unlzw(Path(fileNameFull).read_bytes()))lines=unCompress.readlines()# do what ever with lines.

(6.2)Java ⭐️

org.apache.commons.compress

 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.24.0</version></dependency>
import org.apache.commons.compress.compressors.z.ZCompressorInputStream;
...try(BufferedReader br = new BufferedReader(new InputStreamReader(new ZCompressorInputStream(Files.newInputStream(Paths.get(SourceFile))), Charset.forName("GBK"))))
{String aLine;while((aLine=br.readLine()) != null) {// do what ever with every Line.}
}

(6.3)Golang ⭐️

github.com/hotei/dcompress

import (..."github.com/hotei/dcompress"...
)
...
fi, err := os.Open(filepath.Join(SourcePath, SourceFile))
if err != nil {panic(err)
}
defer fi.Close()
dcompress.Verbose = true
fz, err := dcompress.NewReader(OneIn)
if err != nil {panic(err)
}
OneReader := bufio.NewReader(fz)
for {line, _, err := OneReader.ReadLine()if err == io.EOF {MyEof = truebreak}if err != nil {panic(err)}// do what ever with every Line.
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/108797.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GO-unioffice实现word编辑

导包 import ("fmt""log""os""time""github.com/unidoc/unioffice/common/license""github.com/unidoc/unioffice/document" ) 创建word文件 func CreateFile(name string) {filename : name ".docx&quo…

NCV7724DQBR2G车规级半桥电机驱动芯片-专为汽车,工业自动化应用提供完美解决方案

车规级半桥电机驱动芯片是一种用于驱动直流电机的芯片&#xff0c;常用于电动汽车、电动自行车等领域。它可以控制电机的转速和方向&#xff0c;并且具有过流保护、过温保护等功能&#xff0c;可以保证电机的安全运行。 NCV7724DQBR2G是一款车规级八通道半桥驱动器&#xff0c;…

新手最容易触发的10个PHP语言Bug分享

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

MyBatisPlue-03

一 映射匹配兼容机制 1.映射数据库的字段名 问题描述&#xff1a; 当数据库表字段和实体类的属性名称出现不匹配时&#xff1a; 解决&#xff1a; 知识点&#xff1a; 2.忽略实体类的部分字段 问题描述&#xff1a; 当要表示如 显示用户是否在线等消息&#xff0c;&#xf…

ArcGis打开影像显示全黑解决方法

我们加载图像&#xff0c;显示如下&#xff1a; 解决方法&#xff1a; 问题分析&#xff1a;Gamma值高于1影像亮化&#xff0c;低于1影像暗化。栅格影像导入进来呈现黑色&#xff0c;可能是因为影像的“Gamma校正”设置出现问题&#xff0c;影响了影像的拉伸度、亮度、对比度等…

基于人工电场优化的BP神经网络(分类应用) - 附代码

基于人工电场优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于人工电场优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.人工电场优化BP神经网络3.1 BP神经网络参数设置3.2 人工电场算法应用 4.测试结果…

Apache Doris 在小鹅通的应用实践

峰会官网已上线&#xff0c;最新议程请关注&#xff1a;doris-summit.org.cn 点击报名 先到先得 本文导读&#xff1a; 随着网络直播规模的不断扩大&#xff0c;在线知识服务在直播行业中迎来了广阔的发展机遇。小鹅通作为一家以用户服务为核心的技术服务商&#xff0c;通过多平…

检测密码安全强度 和 凯撒加密

检测密码安全强度 按照含有数字,小写字母,大写字母,指定标点符号的种类,把安全强度分为强密码,中高,中低,弱密码. 编写程序,输入一个字符串,输出该字符串作为密码时的安全强度 from string import digits, ascii_lowercase, ascii_uppercasedef check(pwd):# 密码必须至少包含…

6、docker下mysql修改配置文件

1、查看mysql镜像 如果没有mysql镜像则下载 docker images |grep mysql 2、查看mysql容器 docker ps |grep mysql 如果没有显示mysql容器信息&#xff0c;则创建 3、创建容器 docker run -it --name mysql-test -e MYSQL_ROOT_PASSWORDroot -p 3306:3306 -d f9653 4、在…

uni-app--》基于小程序开发的电商平台项目实战(六)

&#x1f3cd;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名在校大学生 &#x1f6f5;个人主页&#xff1a;亦世凡华、 &#x1f6fa;系列专栏&#xff1a;uni-app &#x1f6b2;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

《Node.js+Express+MongoDB+Vue.js全栈开发实战》简介

今天介绍的这本书是《Node.jsExpressMongoDBVue.js全栈开发实战》。该书由清华大学出版社于2023年1月出版 外观 从书名故名思议&#xff0c;就是基于Node.jsExpressMongoDBVue.js来实现企业级应用全栈开发。 封面风格比较简约&#xff0c;插图是一张类似于罗马时代战车形象&…

Leetcode刷题详解——找到字符串中所有字母异位词

1. 题目链接&#xff1a;438. 找到字符串中所有字母异位词 2. 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括…

C语言---预处理详解

1.预定义符号 在C语言中有一些内置的预定义符号 __FILE__ __LINE__ __DATE__ __TIME__ __STDC__//进行编译的源文件 //文件当前的行号 //文件被编译的日期 //文件被编译的时间 //如果编译器遵循ANSI C&#xff0c;其值为1&#xff0c;否则未定义 编译器在__STDC__报错,说明,v…

【TES720D】青翼科技基于复旦微的FMQL20S400全国产化ARM核心模块

板卡概述 TES720D是一款基于上海复旦微电子FMQL20S400的全国产化核心模块。该核心模块将复旦微的FMQL20S400&#xff08;兼容FMQL10S400&#xff09;的最小系统集成在了一个50*70mm的核心板上&#xff0c;可以作为一个核心模块&#xff0c;进行功能性扩展&#xff0c;特别是用…

【数组的使用】

文章目录 前言数组的格式有两种数组是引用数据类型遍历数组获取数组的长度&#xff1a;数组名.length数组之间的引用数组中的null关于引用的注意事项总结 前言 数组的格式有两种 int[] array{1,2,3,4};int[] array2new int[10];//默认将数组进行初始化&#xff0c;里面的值都为…

问:TCP/IP协议栈在内核态的好还是用户态的好

“TCP/IP协议栈到底是内核态的好还是用户态的好&#xff1f;” 问题的根源在于&#xff0c;干嘛非要这么刻意地去区分什么内核态和用户态。 引子 为了不让本文成为干巴巴的说教&#xff0c;在文章开头&#xff0c;我以一个实例分析开始。 最近一段时间&#xff0c;我几乎每…

idea使用debug无法启动,使用run可以启动

1、将调试断点清除 使用快捷键ctrl shift F8&#xff0c;将勾选的选项去除即可 2、Error running SampleApplication: Command line is too long. Shorten command line for SampleApplication or also for Spring Boot default configuration&#xff0c;报这种错误&#x…

tcp/ip协议2实现的插图,数据结构2 (9 - 章)

&#xff08;20&#xff09; 20 九章1 IP选项处理 ip_dooptions &#xff08;21&#xff09; 21 九章2 IP选项处理 ip_rtaddr,save_rte,ip_srcroute与结构体 &#xff08;22&#xff09;九章3 IP选项处理 ip_pcbopts, ip_insertoptions , iptime 与结构 &#xff08;23&#xf…

过滤器(Filter)和拦截器(Interceptor)有什么不同?

过滤器&#xff08;Filter&#xff09;和拦截器&#xff08;Interceptor&#xff09;是用于处理请求和响应的中间件组件&#xff0c;但它们在实现方式和应用场景上有一些不同。 实现方式: 过滤器是Servlet规范中定义的一种组件&#xff0c;通常以Java类的形式实现。过滤器通过在…

大数据Flink(九十八):SQL函数的归类和引用方式

文章目录 SQL函数的归类和引用方式 一、SQL 函数的归类