Java压缩中的中文文件名问题(100分)

  • 主题发起人 主题发起人 Sterntaler
  • 开始时间 开始时间
S

Sterntaler

Unregistered / Unconfirmed
GUEST, unregistred user!
我用java.util.jar做了个压缩/解压缩程序,有几个问题:
1、中文文件名压缩后变成乱码文件名。
2、解压缩的时候获取的文件大小信息不正确(-1)。
3、进度条闪烁(每次调用paint(),不然不刷新)。
源代码在
http://www.playicq.com/dispdocnew.php?id=11465
 
-------在win平台上 没问题呀压缩中文名的文件,解压缩也没问题
class zipfile //压缩
{
public zipfile(String filename,String zipfilename)
{
try
{
//打开需压缩文件作为文件输入流
FileInputStream fin=new FileInputStream(filename);
//建立压缩文件输出流
FileOutputStream fout=new FileOutputStream(zipfilename);
//建立gzip压缩输出流
GZIPOutputStream gzout=new GZIPOutputStream(fout);
byte[] buf=new byte[1024];//设定读入缓冲区尺寸
int num;
while ((num=fin.read(buf)) != -1)
{
gzout.write(buf,0,num);
}
gzout.close();//!!!关闭流,必须关闭所有输入输出流.保证输入输出完整和释放系统资源.
fout.close();
fin.close();
}
catch(IOException e)
{
System.out.println(e);
}
}
}
class unzipfile //解压缩
{
public unzipfile(String unzipfilename,String filename)
{
try
{
//建立gzip压缩文件输入流
FileInputStream fin=new FileInputStream(unzipfilename);
//建立gzip解压工作流
GZIPInputStream gzin=new GZIPInputStream(fin);
//建立解压文件输出流
FileOutputStream fout=new FileOutputStream(filename);
byte[] buf=new byte[1024];
int num;
while ((num=gzin.read(buf,0,buf.length)) != -1)
{
fout.write(buf,0,num);
}
gzin.close();
fout.close();
fin.close();
}catch(IOException e)
{
System.out.println(e);
}
}
}
public class mailadd
{
public static void main(String args[])
{
new zipfile("d://我爱.mdb","d://1.zip")
//new unzipfile("d://1.zip","d://我爱.mdb");
}
}
 
javac -h
-encoding <encoding> Specify character encoding used by source files
尽量不要在java源文件中出现中文。
 
谢谢 7syw, 是我没有交待清楚。
你看看下面的完整源码就理解我的意思了:
 
/** Jar and UnJar
* Jar.java
* Anyone can use this file freely
*
* Last updated by Sterntaler 2003-12-17
* faults: Could not resolve Unicode filename while jar
*/
/* ---------------------------------------------
// example: TestJar.java
package util.compress;
public class TestJar implements Jar.ProgressListener{
public void JarProcessbegin
(int totalFiles, long totalSize){
System.out.println("begin
, Total: " + totalFiles + " files, " + totalSize / 1024 + "K");
}
public void JarProcess(int totalFiles, long totalSize, long fileSize){
System.out.println("Current size: " + fileSize);
}
public void JarProcessEnd(int totalFiles, long totalSize){
System.out.println("Operation Completed.");
}

public static void main(String[] args){
TestJar test = new TestJar();
Jar jar = new Jar();
jar.addProgressListener(test);
jar.jar("d://clock", "e://clk.jar");
}
}
*/
package util.compress;
import java.util.ArrayList;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.JarInputStream;

public class Jar{
final int BUF_SIZE = 1024 * 64;
private int[] m_totalFiles = {0};
// for progress suport
private long[] m_totalSize = {0};

private ArrayList progressListeners = null;

public Jar(){
progressListeners = new ArrayList();
}

public void addProgressListener(ProgressListener pl){
progressListeners.add(pl);
}

public void removeProgressListener(ProgressListener pl){
progressListeners.remove(progressListeners.indexOf(pl));
}

private void onProgressbegin
(int totalFiles, long totalSize){
if (!progressListeners.isEmpty()){
for (int i = 0;
i < progressListeners.size();
i++){
ProgressListener pl = (ProgressListener)progressListeners.get(i);
pl.JarProcessbegin
(totalFiles, totalSize);
}
}
}

private void onProgressEnd(int totalFiles, long totalSize){
if (!progressListeners.isEmpty()){
for (int i = 0;
i < progressListeners.size();
i++){
ProgressListener pl = (ProgressListener)progressListeners.get(i);
pl.JarProcessEnd(totalFiles, totalSize);
}
}
}

private void onProgress(int totalFiles, long totalSize, long fileSize){
if (!progressListeners.isEmpty()){
for (int i = 0;
i < progressListeners.size();
i++){
ProgressListener pl = (ProgressListener)progressListeners.get(i);
pl.JarProcess(totalFiles, totalSize, fileSize);
}
}
}

/** Get all summaray information of the directory.
* @param dir The given directory
* @param totalFiles Retrives file count of the directory
* @param totalSize Retrives sum file size of the directory
* @return true if successfully retrieves the values.
*/
boolean sumFileSize(String dir, int[] totalFiles, long[] totalSize){
File file = null;
try {
file = new File(dir);
File[] files = file.listFiles();
if (files == null){
if (!file.isDirectory()){ totalFiles[0]++;
totalSize[0] += file.length();
}
} else
for (int i = 0;
i < files.length;
i++){
if (files.isDirectory() &amp;&amp;
!files.getName().equals(".") &amp;&amp;
!files.getName().equals(".."))
sumFileSize(files.getPath(), totalFiles, totalSize);
else
{ totalFiles[0]++;
totalSize[0] += files.length();
}
}
return true;
} catch (Exception e){ return false;
}
}

boolean sumFileSize(String[] dirs, int[] totalFiles, long[] totalSize){
int[] fileCount = {0};
long[] fileSize = {0};
if (dirs == null || dirs.length < 1) return false;

for (int i = 0;
i < dirs.length;
i++){
sumFileSize(dirs, fileCount, fileSize);
totalFiles[0] += fileCount[0];
totalSize[0] += fileSize[0];
fileCount[0] = 0;
fileSize[0] = 0;
}
return true;
}

/** Get information from jar file
* @param jarFile target jar file
* @param totalFiles To retrieve total file count
* @param totalSize To retrieve total file size
* @return true if no error occurs.
*
* Did not work probably
*/
private boolean getJarFileInfo(String jarFile, int[] totalFiles, long[] totalSize){
try {
JarInputStream jis = new JarInputStream(new FileInputStream(jarFile));
ZipEntry ze;
while ((ze = jis.getNextEntry()) != null){
totalFiles[0]++;
totalSize[0] += ze.getSize();
}
return true;
} catch (Exception e){ return false;
}
}

public boolean unJar(File jarFile, File destDir){
return unJar(jarFile.getPath(), destDir.getPath());
}

/** UnJar
* @param jarFile jar file name.
* @param destDir Director to extract the files in the jar file
* @return true if successful
*/
public boolean unJar(String jarFile, String destDir){
try {
getJarFileInfo(jarFile, m_totalFiles, m_totalSize);
onProgressbegin
(m_totalFiles[0], m_totalSize[0]);
FileInputStream fis = new FileInputStream(jarFile);
JarInputStream jis = new JarInputStream(fis);
ZipEntry ze = null;

File file = new File(destDir);
if (!destDir.endsWith(file.separator)) destDir = destDir.concat(file.separator);

if (!file.exists() &amp;&amp;
!file.mkdir()){
System.out.println("Cannot make dir.");
return false;
}

FileOutputStream fos = null;
byte[] buf = new byte[BUF_SIZE];
int readSize = 0;
File dir = null;
String dirName;
while ((ze = jis.getNextJarEntry()) != null) {
dirName = destDir + ze.getName();
file = new File(destDir + ze.getName());
dirName = dirName.substring(0, dirName.length() - file.getName().length());
dir = new File(dirName);
if (!dir.exists() &amp;&amp;
!dir.mkdirs()){
System.out.println("Cannot make dir.");
return false;
}

if (ze.isDirectory()){
System.out.println("*** DIR ***");
// if (!file.mkdir()) return false;
} else
{
file.createNewFile();
onProgress(m_totalFiles[0], m_totalSize[0], ze.getSize());
fos = new FileOutputStream(file);
while ((readSize = jis.read(buf, 0, BUF_SIZE)) > 0)
fos.write(buf, 0, readSize);
fos.close();
}
}/** while ((ze = jis.getNextJarEntry()) != null) { */
jis.close();
fis.close();
onProgressEnd(m_totalFiles[0], m_totalSize[0]);
return true;
} catch (Exception e){ return false;
}
}

public boolean jar(File srcFile, File jarFile){
return jar(srcFile.getPath(), jarFile.getPath());
}

/** Put one file or director to a jar file
* @param srcFile The file or director to jar
* @param jarFile The destination jar file
* @return true if successful
*/
public boolean jar(String srcFile, String jarFile){
JarOutputStream jos = null;
File file = null;
try {
file = new File(srcFile);
if (!file.exists() || !file.canRead()) return false;

sumFileSize(srcFile, m_totalFiles, m_totalSize);
onProgressbegin
(m_totalFiles[0], m_totalSize[0]);

String curPath = file.getPath().substring(0, file.getPath().length() - file.getName().length());
jos = new JarOutputStream(new FileOutputStream(jarFile)); // overwrite

jarDir(jos, curPath, srcFile);
jos.close();
onProgressEnd(m_totalFiles[0], m_totalSize[0]);
return true;
} catch (Exception e){ return false;
}
}

public boolean jar(File[] srcFiles, File jarFile){
if (srcFiles == null || srcFiles.length < 1) return false;
String[] fileNames = new String[srcFiles.length];
for (int i = 0;
i < srcFiles.length;
i++)
fileNames = srcFiles.getPath();
return jar(fileNames, jarFile.getPath());
}

/** Put multi file or director to a jar file
* @param srcFiles The files or directors to jar
* the first file's directory is used for current directory
* @param jarFile The destination jar file
* @return true if successful
*/
public boolean jar(String[] srcFiles, String jarFile){
JarOutputStream jos = null;
File file = null;
try {
if (srcFiles == null || srcFiles.length < 1) return false;
file = new File(srcFiles[0]);
if (!file.exists() || !file.canRead()) return false;
sumFileSize(srcFiles, m_totalFiles, m_totalSize);
onProgressbegin
(m_totalFiles[0], m_totalSize[0]);
String curPath = file.getPath().substring(0, file.getPath().length() - file.getName().length());
jos = new JarOutputStream(new FileOutputStream(jarFile)); // overwrite
for (int i = 0;
i < srcFiles.length;
i++)
if (!jarDir(jos, curPath, srcFiles)) return false;
jos.close();
onProgressEnd(m_totalFiles[0], m_totalSize[0]);
return true;
} catch (Exception e){ return false;
}
}

/** Jar one directory or file
*/
private boolean jarDir(JarOutputStream jos, String curPath, String srcDir){
try {
File file = new File(srcDir);
File[] files = file.listFiles();
if (files == null){
if (!file.isDirectory())do
Jar(jos, curPath, file.getPath());
} else
for (int i = 0;
i < files.length;
i++){
if (files.isDirectory() &amp;&amp;
!files.getName().equals(".") &amp;&amp;
!files.getName().equals(".."))
jarDir(jos, curPath, files.getPath());
else
do
Jar(jos, curPath, files.getPath());
}
return true;
} catch (Exception e){ return false;
}
}

/**do
the jar job
* compress the stream and make a jar file.
*/
private booleando
Jar(JarOutputStream jos, String curPath, String fullFileName){
try {
File file = new File(fullFileName);
if (!file.isDirectory()){ // if file is directory,do
n't add entry
onProgress(m_totalFiles[0], m_totalSize[0], file.length());
jos.putNextEntry(new ZipEntry(new String(fullFileName.substring(curPath.length()))));
FileInputStream fis = new FileInputStream(file);

// intdo
neSize = 0;
int readSize = 0;
byte[] buf = new byte[BUF_SIZE];

while ((readSize = fis.read(buf, 0, BUF_SIZE)) > 0){
jos.write(buf, 0, readSize);
//do
neSize += readSize;
}
fis.close();
fis = null;
}

jos.flush();
return true;
} catch (Exception e){ return false;
}
}

private booleando
Jar(JarOutputStream jos, String curPath, File file){
returndo
Jar(jos, curPath, file.getPath());
}
// public static void main(String[] args) throws Exception{
// unJar("e://www.jar", "e://jjj");
// jar("e://src", "e://www.jar");
/**
String[] srcFiles = {"d://work", "d://props.txt"};
jar(srcFiles, "e://w1.jar");*/
/**
int[] totalFiles = {0};
long[] totalSize = {0};
sumFileSize("d://props.txt", totalFiles, totalSize);
System.out.println(totalSize[0]);*/
// }

interface ProgressListener{
public void JarProcessbegin
(int totalFiles, long totalSize);
public void JarProcess(int totalFiles, long totalSize, long fileSize);
public void JarProcessEnd(int totalFiles, long totalSize);
}
}
 
package util.compress;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JarTool implements Jar.ProgressListener, ActionListener{
final static String m_title = "JarTool";
JFrame frame;
JButton btnJar, btnUnJar;
JProgressBar pbProgress;

long processedSize;

public void JarProcessbegin
(int totalFiles, long totalSize){
pbProgress.setMaximum((int)Math.abs(totalSize));
processedSize = 0;
frame.setTitle(m_title + " ...");
}
public void JarProcess(int totalFiles, long totalSize, long fileSize){
processedSize += fileSize;
pbProgress.setValue((int)Math.abs(processedSize));
// System.out.println(100 * processedSize / totalSize + "%");
pbProgress.setString(100 * processedSize / totalSize + "%");
pbProgress.paint(pbProgress.getGraphics());
}
public void JarProcessEnd(int totalFiles, long totalSize){
pbProgress.setValue((int)Math.abs(totalSize));
pbProgress.setValue(0);
JOptionPane.showMessageDialog(null, "Completed!");
frame.setTitle(m_title);
}

voiddo
Compress(){
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("Choose files to compress");
chooser.setMultiSelectionEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
int returnVal = chooser.showOpenDialog(frame);
if(returnVal == JFileChooser.APPROVE_OPTION) {
JFileChooser fcSave = new JFileChooser();
fcSave.setDialogTitle("Specify a file to save");
int ret = fcSave.showSaveDialog(frame);
if (ret == JFileChooser.APPROVE_OPTION) {
Jar compresser = new Jar();
compresser.addProgressListener(this);
compresser.jar(chooser.getSelectedFiles(), fcSave.getSelectedFile());
}
}
}

voiddo
DeCompress(){
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("Choose a zip/jar file:");
int returnVal = chooser.showOpenDialog(frame);
if(returnVal == JFileChooser.APPROVE_OPTION) {
JFileChooser fcSave = new JFileChooser();
fcSave.setDialogTitle("Choose a directory for decompressed files:");
fcSave.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
int ret = fcSave.showSaveDialog(frame);
if (ret == JFileChooser.APPROVE_OPTION) {
Jar deCompresser = new Jar();
deCompresser.addProgressListener(this);
deCompresser.unJar(chooser.getSelectedFile(), fcSave.getSelectedFile());
}
}
}

public void actionPerformed(ActionEvent ae){
if (ae.getSource() == btnJar)do
Compress();
else
if (ae.getSource() == btnUnJar)do
DeCompress();

}

public JarTool(){
processedSize = 0;
initFrame();
}

public void initFrame(){
frame = new JFrame("Jar tool");
btnJar = new JButton("Compress");
btnUnJar = new JButton("Decompress");
btnJar.addActionListener(this);
btnUnJar.addActionListener(this);
pbProgress = new JProgressBar();
pbProgress.setStringPainted(true);

JPanel pane = (JPanel)frame.getContentPane();
pane.setLayout(new BorderLayout());
JPanel pbContainer = new JPanel();
pbContainer.add(pbProgress);
pane.add(pbContainer, BorderLayout.CENTER);
JPanel btnContainer = new JPanel();
btnContainer.add(btnJar);
btnContainer.add(btnUnJar);
pane.add(btnContainer, BorderLayout.SOUTH);

frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}

public static void main(String[] args){
JarTool test = new JarTool();
}
}
 
其中
造成 1:
-> jos.putNextEntry(new ZipEntry(new String(fullFileName.substring(curPath.length()))));
造成 2:
-> totalSize[0] += ze.getSize();
-> onProgress(m_totalFiles[0], m_totalSize[0], ze.getSize());
造成 3:
-> pbProgress.paint(pbProgress.getGraphics());
 
是否有点乱了呢,唉。我说清楚了没有?
 
to 7syw:
使用你的 zipfile 压缩之后,压缩包里面只有文件名(no ext)。
打包后的程序(for windows)在
http://www.playicq.com/dispdocnew.php?id=11620
还存在同样的问题。
 
后退
顶部