Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 4 of 4

Thread: ZIP file created in JAVA doesn't work as it is

  1. #1
    Junior Member
    Join Date
    Jul 2012
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default ZIP file created in JAVA doesn't work as it is

    I've recently decided to write a launcher for my project. It simply downloads updated files from my server, unpacks them, merges some of the files (because their content varies on settings of the launcher) and packs them into one .zip file.

    I'm sure the downloading and merging processes work perfectly, but the last one - zipping - doesn't.

    The .zip file is created correctly, but when I put it into the game dir, the game won't start (says it's corrupted). But if I open it with WinRar (yes, it opens without errors - the "Test" function shows no errors, too) and just add one, random file inside, the game STARTS!

    Seems like WinRar re-creates the zip file in a correct way, but I can't make my launcher to do so.

    Here's my code:
                      private static void zipDir(String zipFileName, String dir) throws Exception {
    		    File dirObj = new File(dir);
    		    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
    		    System.out.println("Creating : " + zipFileName);
    		    addDir(dirObj, out);
    		    out.close();
    		  }
     
    		  static void addDir(File dirObj, ZipOutputStream out) throws IOException {
    		    File[] files = dirObj.listFiles();
    		    byte[] tmpBuf = new byte[1024];
     
    		    for (int i = 0; i < files.length; i++) {
    		      if (files[i].isDirectory()) {
    		        addDir(files[i], out);
    		        continue;
    		      }
    		      String fap = files[i].getAbsolutePath();
    		      String rel_path = fap.substring(fap.indexOf("wypakowane") + 11).replace("\\", "/");
    		      FileInputStream in = new FileInputStream(fap);
    		      System.out.println(" Adding: " + rel_path);
    		      out.putNextEntry(new ZipEntry(rel_path));
    		      int len;
    		      while ((len = in.read(tmpBuf)) > 0) {
    		        out.write(tmpBuf, 0, len);
    		      }
    		      out.closeEntry();
    		      in.close();
    		    }
    		  }
    ("wypakowane" is the directory that contains all the files I want to put into ZIP file.)

    I just compared both archives - the one created by my java app and the one created by WinRar by adding random file. They are identical, have the same CRCs, same attributes and unpack correctly. But the game crashes with the first one, and runs smoothly with the second one. I'm running out of ideas. Any help?

    EDIT: Okay, here's my whole class file.
    package launcher;
     
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    import java.util.zip.ZipOutputStream;
    import javax.swing.JOptionPane;
    import javax.swing.JLabel;
     
     
    class Files implements Runnable
    {	
    	private final static String SEPARATOR = System.getProperty("file.separator");
    	/** Local dir where the files will be downloaded */
    	static String storage_dir = /*System.getProperty("user.dir") + */"temp";
     
    	/** Local dir where the downloaded zips will be stored */
    	static String download_dir = storage_dir + SEPARATOR + "pobierane";
     
    	/** Local dir where the unpacked files will be stored */
    	static String unpack_dir = storage_dir + SEPARATOR + "wypakowane";
     
    	/** Local dir where the joined files will be stored */
    	static String data_dir = storage_dir + SEPARATOR + "data";
     
    	private String game_dir;
    	private JLabel msg;
     
     
     
     
     
    	Files (String gd, JLabel msg)
    	{
    		game_dir = gd;
    		this.msg = msg;
    	}
     
     
    	public void run()
    	{
    		System.out.println("Wypakowuję pliki");
    		msg.setText("Wypakowuję pliki...");
    		unzipFiles();
    		System.out.println("Łączę pliki");
    		msg.setText("Łączę pliki...");
    		joinAllFiles();
    		System.out.println("Tworzę plik PAK");
    		msg.setText("Tworzę plik PAK...");
    		createPAK();
    		System.out.println("Kopiuję PAK do katalogu gry");
    		msg.setText("Kopiuję PAK do katalogu gry...");
    		copyPAK();
     
    		//unzip("D:\\Gry\\Aion\\l10n\\1_enu\\data\\data.pak", "D:\\testowy");
     
    		System.out.println("Usuwam tymczasowe pliki");
    		msg.setText("Usuwam tymczasowe pliki...");
    		try {
    			delete(new File(unpack_dir));
    			delete(new File(data_dir));
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		createTempDirs();
    	}
     
    	static public void createTempDirs()
    	{
    		String[] dirs_to_create = { download_dir, unpack_dir, data_dir };
    		for (String dir : dirs_to_create)
    		{
    			File f = new File(dir);
    			if (!f.exists()) f.mkdirs();
    		}
    	}
    	public static void joinFiles(String[] files, String output, String main_tag, String encoding)
    	{
    		try
    		{
    			File o = new File(unpack_dir + SEPARATOR + output);
    			if (o.exists()) o.delete();
     
    			FileWriter output_file = new FileWriter(o);
    			output_file.write("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\r\n<" + main_tag + ">");
    			String a;
    			for (String rfn : files)
    			{
    				BufferedReader br = new BufferedReader(new FileReader(unpack_dir + SEPARATOR + rfn));
    				while ((a = br.readLine()) != null)
    				{
    					output_file.write("\r\n" + a);
    				}
    				br.close();
    			}
    			output_file.write("\r\n</" + main_tag + ">");
    			output_file.close();
    		} catch (IOException exc)
    		{
    			System.err.println(exc.toString());
    		}
    	}
     
    	private void joinAllFiles()
    	{
    		String[][] filesToJoin = {
    			{"strings" + SEPARATOR + "client_strings_order.xml", "strings" + SEPARATOR + "client_strings_questy.xml", "strings" + SEPARATOR + "client_strings_quest_items_name.xml", "strings" + SEPARATOR + "client_strings_quest_items_desc.xml", "strings" + SEPARATOR + "client_strings_title_name.xml", "strings" + SEPARATOR + "client_strings_title_desc.xml"},
    			{"strings" + SEPARATOR + "client_strings_skill_name.xml", "strings" + SEPARATOR + "client_strings_skill_desc.xml"},
    			{"strings" + SEPARATOR + "client_strings_item_name.xml", "strings" + SEPARATOR + "client_strings_item_desc.xml"},
    			{"strings" + SEPARATOR + "client_strings_item2_name.xml", "strings" + SEPARATOR + "client_strings_item2_desc.xml"}
    		};
    		String[] destFiles = {
    			"strings" + SEPARATOR + "client_strings_quest.xml",
    			"strings" + SEPARATOR + "client_strings_skill.xml",
    			"strings" + SEPARATOR + "client_strings_item.xml",
    			"strings" + SEPARATOR + "client_strings_item2.xml"
    		};
     
    		String[] destEncodings = {
    			"utf-16",	
    			"utf-16",	
    			"utf-16",	
    			"utf-16"
    		};
    		String[] destTags = {
    			"strings",
    			"strings",
    			"strings",
    			"strings"
    		};
     
    		for (int i=0; i<filesToJoin.length; ++i)
    		{
    			joinFiles(filesToJoin[i], destFiles[i], destTags[i], destEncodings[i]);
    			for (String f : filesToJoin[i])
    			{
    				System.err.println("Usuwam plik: " + f);
    				if (!new File(unpack_dir + SEPARATOR + f).delete()) System.err.println("Nie można usunąć pliku: " + f);
    			}
    		}
    	}
     
    	private void createPAK()
    	{
     
    		//zipMultiRecursively(new File(unpack_dir).list(), data_dir + SEPARATOR + "data.pak");
    		try {
    			zipDir(data_dir + SEPARATOR + "data.zip", unpack_dir);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
     
    	static public int isFileUpdated (URL url, File local)
    	{
    		try {
    			long local_length = 0;
    			if (local.exists()) local_length = local.length();
    			long url_length = url.openConnection().getContentLength();
    			if (url_length == 162) url_length = 0;
    			System.out.println("Sprawdzam: -- LOCAL: " + String.valueOf(local_length) + " --- URL: " + String.valueOf(url_length) + " -- LOCAL: " + local.getPath() + ", URL: " + url.getPath());
    			if (local_length == url_length) return 1; else return 0;
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return -1;
    	}
     
    	private void copyPAK()
    	{
    		String destPath = game_dir + SEPARATOR + "l10n" + SEPARATOR + "1_enu" + SEPARATOR + "data";
    		String data = getRealPath(destPath);
    		if (data == "") {
    			try {
    				java.nio.file.Files.createDirectories(new File(destPath).toPath());
    				data = destPath;
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    			System.out.println("Tworzę potrzebne foldery w katalogu gry -- " + data); 
    		}
    		if (new File(data).exists()) 
    		{
    			try {
    				if (!java.nio.file.Files.move(
    						new File(data_dir + SEPARATOR + "data.zip").toPath(), 
    						new File(data + SEPARATOR + "data.pak").toPath(), 
    						java.nio.file.StandardCopyOption.REPLACE_EXISTING).toFile().exists()) 
    					JOptionPane.showMessageDialog(null, "Nie można skopiować paczki do folderu: " + data);
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
     
    		}
    	}
     
    	private String getRealPath(String pathToCheck)
    	{
    		StringBuffer path = new StringBuffer();
    		String[] pathSlices = pathToCheck.split("@" + SEPARATOR + "@");
     
    		for (String dir : pathSlices)
    		{
    			File currentDir = new File(dir);
    			// Folder istnieje, dodaj go do ścieżki
    			if (currentDir.exists())
    				path.append(currentDir + SEPARATOR);
    			// Folder nie istnieje, sprawdź, czy jest pod inną nazwą
    			else
    			{
    				if (path.length() == 0) return "";
    				String[] currentPathFiles = new File(path.toString()).list();
    				for (String c : currentPathFiles)
    				{
    					if (c.toLowerCase() == dir.toLowerCase())
    					{
    						path.append(c + SEPARATOR);
    						break;
    					}
    				}
    			}
    		}
    		return path.toString();
    	}
     
    	static public ArrayList<String> getFilesToDownload(ArrayList<String> server_files)
    	{
    		ArrayList<String> filestodownload = new ArrayList<String>();
     
    		String fn;
    		for (String sv : server_files)
    		{
    			fn = sv.substring(sv.lastIndexOf('/') + 1);
    			try {
    				int updated = isFileUpdated(new URL(sv), new File(download_dir + SEPARATOR + fn));
    				if (updated == 0)
    				{
    					System.out.println("Muszę pobrać: -- LOCAL: " + fn + " --- URL: " + sv);
    					filestodownload.add(sv);
    				}
    				else if (updated == -1)
    				{
    					JOptionPane.showMessageDialog(null, "Plik: " + fn + " nie może zostać pobrany. Zgłoś to do kogoś z IronSquadu!");
    					return new ArrayList<String>();
    				}
    			} catch (MalformedURLException e) {
    				e.printStackTrace();
    			}
    		}
     
    		return filestodownload;
    	}
     
        @SuppressWarnings("rawtypes")
    	private static void unzip(String strZipFile, String strDest) {
            try
            {
                    File fSourceZip = new File(strZipFile);
                    String zipPath = strDest;
                    //System.out.println(zipPath + " created");
     
                    ZipFile zipFile = new ZipFile(fSourceZip);
                    Enumeration e = zipFile.entries();
     
                    while(e.hasMoreElements())
                    {
                            ZipEntry entry = (ZipEntry)e.nextElement();
                            File destinationFilePath = new File(zipPath,entry.getName());
     
                            //create directories if required.
                            destinationFilePath.getParentFile().mkdirs();
     
                            //if the entry is directory, leave it. Otherwise extract it.
                            if(entry.isDirectory())
                            {
                            	continue;
                            }
                            else
                            {
                                //System.out.println("Extracting " + destinationFilePath);
     
                                /*
                                 * Get the InputStream for current entry
                                 * of the zip file using
                                 *
                                 * InputStream getInputStream(Entry entry) method.
                                 */
                                BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
     
                                int b;
                                byte buffer[] = new byte[1024];
     
                                /*
                                 * read the current entry from the zip file, extract it
                                 * and write the extracted file.
                                 */
                                FileOutputStream fos = new FileOutputStream(destinationFilePath);
                                BufferedOutputStream bos = new BufferedOutputStream(fos, 1024);
     
                                while ((b = bis.read(buffer, 0, 1024)) != -1) 
                                {
                                	bos.write(buffer, 0, b);
                                }
     
                                //flush the output stream and close it.
                                bos.flush();
                                bos.close();
     
                                //close the input stream.
                                bis.close();
                            }
                    }
                    zipFile.close();
            }
            catch(IOException ioe)
            {
                    System.out.println("IOError :" + ioe + " -- IN FILE: " + strZipFile);
            }
     
        }
     
    	private void unzipFiles()
    	{
    		String[] files_to_unzip = new File(download_dir).list();
    		for (String file : files_to_unzip)
    		{
    			unzip(download_dir + SEPARATOR + file, unpack_dir);
    		}
    	}
     
    	public static void delete(File f) throws IOException {
    		  if (f.isDirectory()) {
    		    for (File c : f.listFiles())
    		      delete(c);
    		  }
    		  if (!f.delete())
    		    throw new FileNotFoundException("Failed to delete file: " + f);
    	}
     
    	  private static void zipDir(String zipFileName, String dir) throws Exception {
    		    File dirObj = new File(dir);
    		    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
    		    System.out.println("Creating : " + zipFileName);
    		    addDir(dirObj, out);
    		    out.close();
    		  }
     
    		  static void addDir(File dirObj, ZipOutputStream out) throws IOException {
    		    File[] files = dirObj.listFiles();
    		    byte[] tmpBuf = new byte[1024];
     
    		    for (int i = 0; i < files.length; i++) {
    		      if (files[i].isDirectory()) {
    		        addDir(files[i], out);
    		        continue;
    		      }
    		      String fap = files[i].getAbsolutePath();
    		      String rel_path = fap.substring(fap.indexOf("wypakowane") + 11).replace("\\", "/");
    		      FileInputStream in = new FileInputStream(fap);
    		      System.out.println(" Adding: " + rel_path);
    		      out.putNextEntry(new ZipEntry(rel_path));
    		      int len;
    		      while ((len = in.read(tmpBuf)) > 0) {
    		        out.write(tmpBuf, 0, len);
    		      }
    		      out.closeEntry();
    		      in.close();
    		    }
    		  }
     
    	static void zipMultiRecursively(String[] sourceDir, String zipFile)
    	{
            try
            {
                //create object of FileOutputStream
                FileOutputStream fout = new FileOutputStream(zipFile);
     
                //create object of ZipOutputStream from FileOutputStream
                ZipOutputStream zout = new ZipOutputStream(fout);
     
                //create File object from source directory
                for (int i=0; i<sourceDir.length; ++i)
                {
    	            File fileSource = new File(unpack_dir + SEPARATOR + sourceDir[i]);
    	            System.err.println(sourceDir[i]);
    	            addDirectory(zout, fileSource, "");
                }
     
                //close the ZipOutputStream
                zout.close();
     
                System.out.println("Zip file has been created!");
     
            }
            catch(IOException ioe)
            {
                System.out.println("IOException :" + ioe);     
            }
    	}
     
    	private static void addDirectory(ZipOutputStream zout, File fileSource, String path) 
    	{
            //get sub-folder/files list
            File[] files = fileSource.listFiles();
     
     
            path += fileSource.getName() + "/";
            System.out.println("Adding directory " + fileSource.getName() + ", Path: " + path);
            try {
    			zout.putNextEntry(new ZipEntry(path + "/"));
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
     
            for(int i=0; i < files.length; i++)
            {
                //if the file is directory, call the function recursively
                if(files[i].isDirectory())
                {
                	System.err.println("Przekazuję dalej: " + files[i] + ", Path: " + path);
                    addDirectory(zout, files[i], path);
                    continue;
                }
                else
                {
    	            /*
    	             * we are here means, its file and not directory, so
    	             * add it to the zip file
    	             */
     
    	            try
    	            {
    	                System.out.println("Adding file " + path + files[i].getName());
     
    	                //create byte buffer
    	                byte[] buffer = new byte[1024];
     
    	                //create object of FileInputStream
    	                FileInputStream fin = new FileInputStream(files[i]);
     
    	                zout.putNextEntry(new ZipEntry(path + files[i].getName().toLowerCase()));
     
    	                /*
    	                 * After creating entry in the zip file, actually
    	                 * write the file.
    	                 */
    	                int length;
     
    	                while((length = fin.read(buffer)) > 0)
    	                {
    	                   zout.write(buffer, 0, length);
    	                }
     
    	                /*
    	                 * After writing the file to ZipOutputStream, use
    	                 *
    	                 * void closeEntry() method of ZipOutputStream class to
    	                 * close the current entry and position the stream to
    	                 * write the next entry.
    	                 */
     
    	                 zout.closeEntry();
     
    	                 //close the InputStream
    	                 fin.close();
    	            }
    	            catch(IOException ioe)
    	            {
    	            	System.out.println("IOException :" + ioe);                             
    	            }
                }
            }
     
    	}
    }
    Last edited by QooBooS; July 30th, 2012 at 02:34 AM. Reason: Added the whole code


  2. #2
    Member
    Join Date
    Jul 2012
    Posts
    69
    My Mood
    Relaxed
    Thanks
    1
    Thanked 6 Times in 6 Posts

    Default Re: ZIP file created in JAVA doesn't work as it is

    I've just got 1 question, why did you decide to send a zip file? I'm working on a launcher as well which will update all the files, but i send them file by file. Im just curious why you made this decision, maybe i should switch over as well then.

  3. #3
    Junior Member
    Join Date
    Jul 2012
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: ZIP file created in JAVA doesn't work as it is

    Ah, you got me wrong. My launcher downloads files one by one, packs them and copies the created archive into the game folder. The output file is data.pak, which is a normal, renamed zip file. If I create it manually with WinRar, it works perfectly.

  4. #4
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: ZIP file created in JAVA doesn't work as it is

    Are you sure all the files in both zip folders are the same? The only thing I can think of is that one of the files didn't write correctly, closed too early, or didn't close at all. I expect this to be one of those extremely difficult problems that has an extremely simple answer.
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

Similar Threads

  1. Jar file does not work with database (Hibernate)
    By shomid in forum JDBC & Databases
    Replies: 2
    Last Post: December 27th, 2011, 11:03 AM
  2. problem in sound files in created jar file
    By uttam24april in forum Member Introductions
    Replies: 48
    Last Post: December 16th, 2011, 07:19 AM
  3. How to make Eclipse work with txt file?
    By Prostak in forum What's Wrong With My Code?
    Replies: 6
    Last Post: November 4th, 2011, 05:43 PM
  4. File IO Compiles, but wont work?
    By StarKannon in forum File I/O & Other I/O Streams
    Replies: 5
    Last Post: February 2nd, 2011, 09:05 AM
  5. [SOLVED] Program to read from created file
    By aznprdgy in forum File I/O & Other I/O Streams
    Replies: 3
    Last Post: April 7th, 2009, 03:51 AM

Tags for this Thread