exe Kopieren

Sunchezz

Bekanntes Mitglied
Halli hallo,
es gibt ein neues Problemchen bei mir.

es ist ja möglich über Reader und Writer Dateien zu kopieren.
Daher sollte es doch auch möglich sein dies eingelesen Dateidaten zu splitten, und in splidateien zwischen zu speichern, quasi die Ursprungsdatei zu splitten.
Das habe ich gerade mit einer Exe vor.
Aus einem verkorksten Grund geht das bei mir nicht.
Liegt das an der Aufbauweise einer exe?


Schonmal herzlichsten Dank!
 
Code:
while (s != null) {
  datei = new ArrayList<String>();
  for (int i = 0; i < 35000; i++) {
     s = in.getReader().readLine(); //BufferedReader
     if (s != null) {
       datei.add(s);
     }
  }
  JlsFileWriter.overwrite(new File(uploadExenFile + "\\Ordner\\" + zaehler + ".exePart"), datei);
  JlsFileWriter.add(new File(uploadExenFile + "\\" + kundenIdentifier + "\\test.exe"), datei); // das ist ja im Prinzip 
                                                                                                                              //     die wieder zusammengefügte datei
   zaehler++;
}

EDIT:
Hier noch die Methode des Writers:

Code:
public static void add(File file, ArrayList<String> content) {
    try {
      FileOutputStream fos = new FileOutputStream(file, true);
      OutputStreamWriter osw = new OutputStreamWriter(fos, Charset.forName("ISO-8859-1"));
      BufferedWriter bw = new BufferedWriter(osw);
      for (int i = 0; i < content.size(); i++) {
        bw.write(content.get(i));
        if (i != content.size()-1) {
          bw.newLine();
        }
      }
      bw.close();
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
 
Zuletzt bearbeitet:
Nimm statt eines BufferedReaders einen normalen InputStream, ein BufferedReader liest Strings ein, du brauchst aber nur Bytes. Definiere einen Buffer mit der Grösse der Datei und speichere immer nach dem einlesen des Buffers eine neue Datei.
 
sollte es nicht aber auch mit Strings gehen?
im prinzip kopiere ich doch den inhalt 1 zu 1 oder??
da sind doch Strings genauso gut???

Werds mal probieren!
 
Für binäre Dateien - also von der exe über das pdf bis zum png oder docx - sollte man - wie bereits erwähnt - keine String-Conversions vornehmen. Da kann man gut mit einem byte[] arbeiten.
 
nur nochmal zum verständnis:

wenn ich das in bytes auslese, (ich hatte es übrigens schon mit ints);
verdreifacht sich doch die gesamt größe...
so wars jedenfalls beim ersten Test.
so wurde aus einer 23MB großen exe, 110MB große Splitdateien^^

das würde ich gerne Vermeiden...

also, wenn ich das in bytes oder ints auslese, werden doch die Ascii werte genommen oder??
heist # = 32546;
so, wenn ich das nun in einer datei zwischenspeicher ist ja klar das die gesamt größe sich verXfacht...
 
Bedenke aber, dass du so die ganze Datei einließt. Dir wird dann wohlirgendwann der RAM ausgehen.
Schau dir mal das an:

Java:
package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class Main
{
	public static void main(String[] args)
	{
		try
		{
			copyFile(new File("Y:\\copy\\Knoppix 5.1.0 - 30. 12. 2006 - Deutsch.iso"),
					new File("Y:\\copy\\target.iso"), 32 * 1024 * 1024 /*32 MB*/);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	/**
	 * Kopiert eine Datei.
	 * @param source Die ursprüngliche Datei.
	 * @param target Die neue Dateinamenbasis. Dieser werden der Reihe nach die Extensions ".partN", also .part1,
	 * .part2 usw angehängt.
	 * @param chunkSize Die Größe der Parts. Darf keinesfalls höher als der der VM zu Verfügung gestellte RAM
	 * sein. 
	 * @throws Falls eine IOException fliegt.
	 */
	public static void copyFile(File source, File target, int chunkSize) throws IOException
	{
		String targetNameBase = target.getAbsolutePath();
		
		FileInputStream in = null;
		FileOutputStream out = null;
	
		FileChannel inChannel = null;
		FileChannel outChannel = null;
	
		try
		{
			in = new FileInputStream(source);
			inChannel = in.getChannel();
	    	
			long fileLenght = source.length();
	    	
			long bytesTransfered = 0L;
			for(int i = 1; bytesTransfered < fileLenght; i++)
			{
				long bytesToTransfer = Math.min(chunkSize, fileLenght - bytesTransfered);
				
				File realTargetFile = new File(targetNameBase + ".part" + i);
				if(!realTargetFile.exists())
					realTargetFile.createNewFile();

				try
				{
					out = new FileOutputStream(realTargetFile);
					outChannel = out.getChannel();
					
					long nowBytesTransfered = inChannel.transferTo(bytesTransfered, bytesToTransfer, outChannel);
					bytesTransfered += nowBytesTransfered;
				}
				finally
				{
					try
					{
						if(outChannel != null)
							outChannel.close();
					}
					catch (IOException e)
					{
						e.printStackTrace();
					}
			
					try
					{
						if(out != null)
						{
							out.flush();
							out.close();
						}
					}
					catch (IOException e)
					{
						e.printStackTrace();
					}
				}
			}
		}
		finally
		{
			try
			{
				if(inChannel != null)
					inChannel.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			
			try
			{
				if(in != null)
					in.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}
}

Edit: Sowas darf natürlich nicht passieren, da musst du einen schweren Fehler gemacht haben. 1 Byte ist immer 1 Byte lang, egal ob in der Start oder Zieldatei.
# ist übrigens nicht 32546, ASCII hat nur 256 Zeichen und von denen sind 127 schon alleine für Steuerzeichen reserviert. # hat Dez. 35.
 
Zuletzt bearbeitet:
ok, das sieht schonmal verdammt gut aus...
Danke sehr...

dann muss ich jetzt nur noch rausfinden wie ich das wieder umdrehen kann.
Einfach das Prinzip umdrehen?
 
Jep, finde es sogar noch einfacher.

Java:
package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.LinkedList;
import java.util.List;

public class Main
{
	public static void main(String[] args)
	{
		File source = new File("Y:\\copy\\Knoppix 5.1.0 - 30. 12. 2006 - Deutsch.iso");
		File target = new File("Y:\\copy\\target.iso");
		
		try
		{
			splitFile(source, target, 32 * 1024 * 1024);
			source.delete();
			mergeFile(target, source, true);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	/**
	 * Kopiert eine Datei und splitted sie in mehrere Ziele auf.
	 * @param source Die ursprüngliche Datei.
	 * @param target Die neue Dateinamenbasis. Dieser werden der Reihe nach die Extensions ".partN", also .part1,
	 * .part2 usw angehängt.
	 * @param chunkSize Die Größe der Parts. Darf keinesfalls höher als der der VM zu Verfügung gestellte RAM
	 * sein. 
	 * @throws Falls eine IOException fliegt.
	 */
	public static void splitFile(File source, File target, int chunkSize) throws IOException
	{
		String targetNameBase = target.getAbsolutePath();
		
		FileInputStream in = null;
		FileChannel inChannel = null;
	
		try
		{
			in = new FileInputStream(source);
			inChannel = in.getChannel();
	    	
			long fileLenght = source.length();
	    	
			long bytesTransfered = 0L;
			for(int i = 1; bytesTransfered < fileLenght; i++)
			{
				long bytesToTransfer = Math.min(chunkSize, fileLenght - bytesTransfered);
				
				File realTargetFile = new File(targetNameBase + ".part" + i);
				if(!realTargetFile.exists())
					realTargetFile.createNewFile();

				FileOutputStream out = null;
				FileChannel outChannel = null;

				try
				{
					out = new FileOutputStream(realTargetFile);
					outChannel = out.getChannel();
					
					long nowBytesTransfered = inChannel.transferTo(bytesTransfered, bytesToTransfer, outChannel);
					bytesTransfered += nowBytesTransfered;
				}
				finally
				{
					try
					{
						if(outChannel != null)
							outChannel.close();
					}
					catch (IOException e)
					{
						e.printStackTrace();
					}
			
					try
					{
						if(out != null)
						{
							out.flush();
							out.close();
						}
					}
					catch (IOException e)
					{
						e.printStackTrace();
					}
				}
			}
		}
		finally
		{
			try
			{
				if(inChannel != null)
					inChannel.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			
			try
			{
				if(in != null)
					in.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}
	/**
	 * Führt eine zuvor gesplittete Datei wieder zusammen.
	 * @param source Die Dateinamenbasis. Diese muss <b>OHNE</b> ".partN" angegeben werden. 
	 * @param target Die Datei, in die zusammengeführt werden soll.
	 * @param autoclear True, falls benutzte Parts automatisch gelöscht werden sollen, falls wenn nicht.
	 * Gelöscht wird ausschließlich, falls das Schreiben fehlerfrei ausgeführt wurde. 
	 * @throws Falls eine IOException fliegt.
	 */
	public static void mergeFile(File source, File target, boolean autoclear) throws IOException
	{
		String sourceNameBase = source.getAbsolutePath();
		
		FileOutputStream out = null;
		FileChannel outChannel = null;
	
		List<File> deleteFilesList = null;
		if(autoclear)
			deleteFilesList = new LinkedList<File>();
		
		try
		{
			if(!target.exists())
				target.createNewFile();
			
			out = new FileOutputStream(target);
			outChannel = out.getChannel();
			
			File realSourceFile = null;
			for(int i = 1; (realSourceFile = new File(sourceNameBase + ".part" + i)).exists(); i++)
			{
				FileInputStream in = null;
				FileChannel inChannel = null;

				try
				{
					int chunkSize = (int) realSourceFile.length();
					
					in = new FileInputStream(realSourceFile);
					inChannel = in.getChannel();
					
					inChannel.transferTo(0, chunkSize, outChannel);	
				}
				finally
				{
					try
					{
						if(inChannel != null)
							inChannel.close();
					}
					catch (IOException e)
					{
						e.printStackTrace();
					}
					
					try
					{
						if(in != null)
							in.close();
					}
					catch (IOException e)
					{
						e.printStackTrace();
					}
				}
				if(autoclear)
					deleteFilesList.add(realSourceFile);
			}
		}
		finally
		{
			try
			{
				if(out != null)
				{
					out.flush();
					out.close();
				}
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
		if(autoclear)
			for(File f:deleteFilesList)
				f.delete();
	}
}
 
Oookay....
DAS, ist cool 😀

Nein im ernst, danke sehr!
Ich hatte es auch schon eben selbst hinbekommen, allerdings ohne diesen Channel kram, das hatt ich noch nie gesehn, bzw. mich nich mit beschäftigt, bei mir hats auch geklappt, allerdings hat er fürs zusammenfügen ca. 4 Minuten gebraucht.
mit deiner Methode gehts unter einer Sekunde!
Keine Ahnung warum, aber wenns recht is, ist es mir momentan egal!
Setz ich mich später mal mit auseinander...

Darf ich das so benutzen?
Nur um mal höflich zu fragen?
 

Zurück
Oben