下面列出了java.util.jar.JarOutputStream#setLevel ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Creates a {@link SignedJarBuilder} with a given output stream, and signing information.
* <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then
* the archive will not be signed.
* @param out the {@link OutputStream} where to write the Jar archive.
* @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>.
* @param certificate the {@link X509Certificate} used to sign the archive, or
* <code>null</code>.
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public SignedJarBuilder(OutputStream out, PrivateKey key, X509Certificate certificate)
throws IOException, NoSuchAlgorithmException {
mOutputJar = new JarOutputStream(new BufferedOutputStream(out));
mOutputJar.setLevel(9);
mKey = key;
mCertificate = certificate;
if (mKey != null && mCertificate != null) {
mManifest = new Manifest();
Attributes main = mManifest.getMainAttributes();
main.putValue("Manifest-Version", "1.0");
main.putValue("Created-By", "1.0 (Android)");
mBase64Encoder = new BASE64Encoder();
mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
}
}
/**
* Creates a {@link SignedJarBuilder} with a given output stream, and signing information.
* <p>If either <code>key</code> or <code>certificate</code> is <code>null</code> then
* the archive will not be signed.
* @param out the {@link OutputStream} where to write the Jar archive.
* @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>.
* @param certificate the {@link X509Certificate} used to sign the archive, or
* <code>null</code>.
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public SignedJarBuilder(OutputStream out, PrivateKey key, X509Certificate certificate)
throws IOException, NoSuchAlgorithmException {
mOutputJar = new JarOutputStream(new BufferedOutputStream(out));
mOutputJar.setLevel(9);
mKey = key;
mCertificate = certificate;
if (mKey != null && mCertificate != null) {
mManifest = new Manifest();
Attributes main = mManifest.getMainAttributes();
main.putValue("Manifest-Version", "1.0");
main.putValue("Created-By", "1.0 (Android)");
mBase64Encoder = Base64.getMimeEncoder();
mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
}
}
/**
* Creates a {@link SignedJarBuilder} with a given output stream, and signing information.
* <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then
* the archive will not be signed.
* @param out the {@link OutputStream} where to write the Jar archive.
* @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>.
* @param certificate the {@link X509Certificate} used to sign the archive, or
* <code>null</code>.
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public SignedJarBuilder(OutputStream out, PrivateKey key, X509Certificate certificate)
throws IOException, NoSuchAlgorithmException {
mOutputJar = new JarOutputStream(new BufferedOutputStream(out));
mOutputJar.setLevel(9);
mKey = key;
mCertificate = certificate;
if (mKey != null && mCertificate != null) {
mManifest = new Manifest();
Attributes main = mManifest.getMainAttributes();
main.putValue("Manifest-Version", "1.0");
main.putValue("Created-By", "1.0 (Android)");
mBase64Encoder = new BASE64Encoder();
mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
}
}
/**
* Creates a {@link SignedJarBuilder} with a given output stream, and signing information.
* <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then
* the archive will not be signed.
* @param out the {@link OutputStream} where to write the Jar archive.
* @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>.
* @param certificate the {@link X509Certificate} used to sign the archive, or
* <code>null</code>.
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public SignedJarBuilder(@NonNull OutputStream out,
@Nullable PrivateKey key,
@Nullable X509Certificate certificate,
@Nullable String builtBy,
@Nullable String createdBy)
throws IOException, NoSuchAlgorithmException {
mOutputJar = new JarOutputStream(new BufferedOutputStream(out));
mOutputJar.setLevel(9);
mKey = key;
mCertificate = certificate;
if (mKey != null && mCertificate != null) {
mManifest = new Manifest();
Attributes main = mManifest.getMainAttributes();
main.putValue("Manifest-Version", "1.0");
if (builtBy != null) {
main.putValue("Built-By", builtBy);
}
if (createdBy != null) {
main.putValue("Created-By", createdBy);
}
mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
}
}
/**
* Create a jar file that contains all the directory listed in directories parameter.
* @param directoriesAndFiles the list of directories and files to be jarred.
* @param manifestVerion the version of the jar manifest (can be null).
* @param mainClass the main class of the jar (can be null).
* @param jarInternalClasspath the class-path of the jar (can be null).
* @param crc the CRC32 of all jar entries. Can be null if no crc is needed.
* @throws IOException if the jar file cannot be created.
* @return the jar file as a byte[].
*/
public static byte[] jarDirectoriesAndFiles(String[] directoriesAndFiles, String manifestVerion, String mainClass,
String jarInternalClasspath, CRC32 crc) throws IOException {
// Fill in a byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Create jar stream
JarOutputStream jos = new JarOutputStream(baos,
JarUtils.createManifest(manifestVerion,
mainClass,
jarInternalClasspath));
jos.setLevel(COMP_LEVEL);
// Jar file is ready
jarIt(jos, directoriesAndFiles, crc);
// Close the file output streams
jos.flush();
jos.close();
baos.flush();
baos.close();
return baos.toByteArray();
}
static public void removeFromJAR (String inJar, String outJar, String... regexs) throws IOException {
if (DEBUG) debug("scar", "Removing from JAR: " + inJar + " -> " + outJar + ", " + Arrays.asList(regexs));
JarFile inJarFile = new JarFile(inJar);
mkdir(parent(outJar));
JarOutputStream outJarStream = new JarOutputStream(new FileOutputStream(outJar));
outJarStream.setLevel(Deflater.BEST_COMPRESSION);
outer:
for (Enumeration<JarEntry> entries = inJarFile.entries(); entries.hasMoreElements();) {
JarEntry inEntry = entries.nextElement();
String name = inEntry.getName();
for (String regex : regexs)
if (name.matches(regex)) continue outer;
JarEntry outEntry = new JarEntry(name);
outEntry.setTime(1370273339); // Reset time.
outJarStream.putNextEntry(outEntry);
copyStream(inJarFile.getInputStream(inEntry), outJarStream);
outJarStream.closeEntry();
}
outJarStream.close();
inJarFile.close();
}
static public void setEntryTime (String inJar, String outJar, long time) throws IOException {
if (DEBUG) debug("scar", "Setting entry to for JAR: " + inJar + " -> " + outJar + ", " + time);
JarFile inJarFile = new JarFile(inJar);
mkdir(parent(outJar));
JarOutputStream outJarStream = new JarOutputStream(new FileOutputStream(outJar));
outJarStream.setLevel(Deflater.BEST_COMPRESSION);
for (Enumeration<JarEntry> entries = inJarFile.entries(); entries.hasMoreElements();) {
JarEntry inEntry = entries.nextElement();
String name = inEntry.getName();
JarEntry outEntry = new JarEntry(name);
outEntry.setTime(time);
outJarStream.putNextEntry(outEntry);
copyStream(inJarFile.getInputStream(inEntry), outJarStream);
outJarStream.closeEntry();
}
outJarStream.close();
inJarFile.close();
}
static public void setClassVersions (String inJar, String outJar, int max, int min) throws IOException {
if (DEBUG) debug("scar", "Setting class versions for JAR: " + inJar + " -> " + outJar + ", " + max + "." + min);
JarFile inJarFile = new JarFile(inJar);
mkdir(parent(outJar));
JarOutputStream outJarStream = new JarOutputStream(new FileOutputStream(outJar));
outJarStream.setLevel(Deflater.BEST_COMPRESSION);
for (Enumeration<JarEntry> entries = inJarFile.entries(); entries.hasMoreElements();) {
String name = entries.nextElement().getName();
outJarStream.putNextEntry(new JarEntry(name));
InputStream input = inJarFile.getInputStream(inJarFile.getEntry(name));
if (name.endsWith(".class")) input = new ClassVersionStream(input, name, max, min);
copyStream(input, outJarStream);
outJarStream.closeEntry();
}
outJarStream.close();
inJarFile.close();
}
/**
* Creates a {@link SignedJarBuilder} with a given output stream, and signing information.
* <p>If either <code>key</code> or <code>certificate</code> is <code>null</code> then
* the archive will not be signed.
* @param out the {@link OutputStream} where to write the Jar archive.
* @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>.
* @param certificate the {@link X509Certificate} used to sign the archive, or
* <code>null</code>.
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public SignedJarBuilder(OutputStream out, PrivateKey key, X509Certificate certificate)
throws IOException, NoSuchAlgorithmException {
mOutputJar = new JarOutputStream(new BufferedOutputStream(out));
mOutputJar.setLevel(4);
mKey = key;
mCertificate = certificate;
if (mKey != null && mCertificate != null) {
mManifest = new Manifest();
Attributes main = mManifest.getMainAttributes();
main.putValue("Manifest-Version", "1.0");
main.putValue("Created-By", "1.0 (Android)");
mBase64Encoder = Base64.getMimeEncoder();
mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
}
}
/**
* Creates a {@link SignedJarBuilder} with a given output stream, and signing information.
* <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then
* the archive will not be signed.
*
* @param out the {@link OutputStream} where to write the Jar archive.
* @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>.
* @param certificate the {@link X509Certificate} used to sign the archive, or
* <code>null</code>.
* @throws IOException
* @throws NoSuchAlgorithmException
*/
public LocalSignedJarBuilder(@NonNull OutputStream out,
@Nullable PrivateKey key,
@Nullable X509Certificate certificate,
@Nullable String builtBy,
@Nullable String createdBy,
@Nullable String signFile) throws IOException, NoSuchAlgorithmException {
mOutputJar = new JarOutputStream(new BufferedOutputStream(out));
mOutputJar.setLevel(9);
mKey = key;
mCertificate = certificate;
mSignFile = signFile;
if (mKey != null && mCertificate != null) {
mManifest = new Manifest();
Attributes main = mManifest.getMainAttributes();
main.putValue("Manifest-Version", "1.0");
if (builtBy != null) {
main.putValue("Built-By", builtBy);
}
if (createdBy != null) {
main.putValue("Created-By", createdBy);
}
mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
}
}
private void writeDependencies(JarOutputStream zOs)
throws IOException
{
Configuration targetConfig;
targetConfig = _project.getConfigurations().getByName("runtime");
for (File lib : targetConfig.resolve()) {
if (isBootJar(lib)) {
copyBootJar(zOs, lib);
}
String name = lib.getName();
zOs.setLevel(0);
ZipEntry entry = new ZipEntry("lib/" + name);
entry.setMethod(ZipEntry.STORED);
entry.setSize(lib.length());
entry.setCrc(calculateCrc(lib.toPath()));
zOs.putNextEntry(entry);
Files.copy(lib.toPath(), zOs);
}
}
private void copyBootJar(JarOutputStream zOs, File bootJar)
throws IOException
{
try (FileInputStream fIn = new FileInputStream(bootJar)) {
zOs.setLevel(9);
try (ZipInputStream zIn = new ZipInputStream(fIn)) {
ZipEntry entry;
String pkg = BaratineBoot.class.getPackage().getName().replace('.', '/') + "/";
while ((entry = zIn.getNextEntry()) != null) {
String name = entry.getName();
if (! name.startsWith(pkg)) {
continue;
}
ZipEntry entryOut = new ZipEntry(name);
entryOut.setSize(entry.getSize());
zOs.putNextEntry(entryOut);
if (name.startsWith(pkg)) {
IoUtil.copy(zIn, zOs);
}
}
}
}
}
/**
* Create a jar with just a manifest containing a Main-Class entry for SurefireBooter and a Class-Path entry for all
* classpath elements. Copied from surefire (ForkConfiguration#createJar())
*
* @param classPath List<String> of all classpath elements.
* @return
* @throws IOException
*/
private File createJar( List<String> classPath, String mainClass )
throws IOException
{
File file = File.createTempFile( "maven-exec", ".jar" );
file.deleteOnExit();
FileOutputStream fos = new FileOutputStream( file );
JarOutputStream jos = new JarOutputStream( fos );
jos.setLevel( JarOutputStream.STORED );
JarEntry je = new JarEntry( "META-INF/MANIFEST.MF" );
jos.putNextEntry( je );
Manifest man = new Manifest();
// we can't use StringUtils.join here since we need to add a '/' to
// the end of directory entries - otherwise the jvm will ignore them.
StringBuilder cp = new StringBuilder();
for ( String el : classPath )
{
// NOTE: if File points to a directory, this entry MUST end in '/'.
cp.append( new URL( new File( el ).toURI().toASCIIString() ).toExternalForm() + " " );
}
man.getMainAttributes().putValue( "Manifest-Version", "1.0" );
man.getMainAttributes().putValue( "Class-Path", cp.toString().trim() );
man.getMainAttributes().putValue( "Main-Class", mainClass );
man.write( jos );
jos.close();
return file;
}
public void doExportDevice(String device) throws Exception {
File ftd = new File(OS.getFolderMyDevices()+File.separator+device+".ftd");
byte buffer[] = new byte[10240];
FileOutputStream stream = new FileOutputStream(ftd);
JarOutputStream out = new JarOutputStream(stream);
out.setLevel(Deflater.BEST_SPEED);
File root = new File(OS.getFolderDevices()+File.separator+device);
int rootindex = root.getAbsolutePath().length();
Collection<File> c = OS.listFileTree(root);
Iterator<File> i = c.iterator();
while (i.hasNext()) {
File entry = i.next();
String name = entry.getAbsolutePath().substring(rootindex-device.length());
if (entry.isDirectory()) name = name+"/";
JarEntry jarAdd = new JarEntry(name);
out.putNextEntry(jarAdd);
if (!entry.isDirectory()) {
InputStream in = new FileInputStream(entry);
while (true) {
int nRead = in.read(buffer, 0, buffer.length);
if (nRead <= 0)
break;
out.write(buffer, 0, nRead);
}
in.close();
}
}
out.close();
stream.close();
}
public void createFTA(String partition, String folder) {
File tadd = new File(folder+File.separator+tafilename);
String timestamp = OS.getTimeStamp();
File fta = new File(folder+File.separator+timestamp+".fta");
byte buffer[] = new byte[10240];
StringBuffer sbuf = new StringBuffer();
sbuf.append("Manifest-Version: 1.0\n");
sbuf.append("Created-By: FlashTool\n");
sbuf.append("serial: "+Devices.getCurrent().getSerial()+"\n");
sbuf.append("build: "+Devices.getCurrent().getBuildId()+"\n");
sbuf.append("partition: "+partition+"\n");
sbuf.append("md5: "+OS.getMD5(tadd).toUpperCase()+"\n");
sbuf.append("timestamp: "+timestamp+"\n");
try {
Manifest manifest = new Manifest(new ByteArrayInputStream(sbuf.toString().getBytes("UTF-8")));
FileOutputStream stream = new FileOutputStream(fta);
JarOutputStream out = new JarOutputStream(stream, manifest);
out.setLevel(Deflater.BEST_SPEED);
logger.info("Creating backupset bundle");
JarEntry jarAdd = new JarEntry(tafilename);
out.putNextEntry(jarAdd);
InputStream in = new FileInputStream(tadd);
while (true) {
int nRead = in.read(buffer, 0, buffer.length);
if (nRead <= 0)
break;
out.write(buffer, 0, nRead);
}
in.close();
out.flush();
out.close();
stream.flush();
stream.close();
tadd.delete();
logger.info("Bundle "+fta.getAbsolutePath()+" creation finished");
}
catch (Exception e) {
logger.error(e.getMessage());
}
}
/** Combines the JARs into one. If both JARs have the same entry, the entry from the first JAR is used. */
static public void mergeJars (String firstJar, String secondJar, String outJar) throws IOException {
if (DEBUG) debug("scar", "Merging JARs: " + firstJar + " + " + secondJar + " -> " + outJar);
JarFile firstJarFile = new JarFile(firstJar);
JarFile secondJarFile = new JarFile(secondJar);
HashSet<String> names = new HashSet();
for (Enumeration<JarEntry> entries = firstJarFile.entries(); entries.hasMoreElements();)
names.add(entries.nextElement().getName().replace('\\', '/'));
for (Enumeration<JarEntry> entries = secondJarFile.entries(); entries.hasMoreElements();)
names.add(entries.nextElement().getName().replace('\\', '/'));
mkdir(parent(outJar));
JarOutputStream outJarStream = new JarOutputStream(new FileOutputStream(outJar));
outJarStream.setLevel(Deflater.BEST_COMPRESSION);
for (String name : names) {
InputStream input;
ZipEntry entry = firstJarFile.getEntry(name);
if (entry != null)
input = firstJarFile.getInputStream(entry);
else {
entry = firstJarFile.getEntry(name.replace('/', '\\'));
if (entry != null)
input = firstJarFile.getInputStream(entry);
else {
entry = secondJarFile.getEntry(name);
input = secondJarFile.getInputStream(entry != null ? entry : secondJarFile.getEntry(name.replace('/', '\\')));
}
}
outJarStream.putNextEntry(new JarEntry(name));
copyStream(input, outJarStream);
outJarStream.closeEntry();
}
firstJarFile.close();
secondJarFile.close();
outJarStream.close();
}
static public void copyFromJAR (String inJar, String outJar, String... regexs) throws IOException {
if (DEBUG) debug("scar", "Copying from JAR: " + inJar + " -> " + outJar + ", " + Arrays.asList(regexs));
JarFile inJarFile = new JarFile(inJar);
mkdir(parent(outJar));
JarOutputStream outJarStream = new JarOutputStream(new FileOutputStream(outJar));
outJarStream.setLevel(Deflater.BEST_COMPRESSION);
for (Enumeration<JarEntry> entries = inJarFile.entries(); entries.hasMoreElements();) {
JarEntry inEntry = entries.nextElement();
String name = inEntry.getName();
boolean matches = false;
for (String regex : regexs) {
if (name.matches(regex)) {
matches = true;
break;
}
}
if (!matches) continue;
JarEntry outEntry = new JarEntry(name);
outJarStream.putNextEntry(outEntry);
copyStream(inJarFile.getInputStream(inEntry), outJarStream);
outJarStream.closeEntry();
}
outJarStream.close();
inJarFile.close();
}
static public void addToJAR (String inJar, String outJar, String addName, byte[] bytes, boolean overwrite) throws IOException {
if (DEBUG) debug("scar", "Adding to JAR: " + inJar + " -> " + outJar + ", " + addName);
JarFile inJarFile = new JarFile(inJar);
mkdir(parent(outJar));
JarOutputStream outJarStream = new JarOutputStream(new FileOutputStream(outJar));
outJarStream.setLevel(Deflater.BEST_COMPRESSION);
ArrayList<String> names = new ArrayList();
for (Enumeration<JarEntry> entries = inJarFile.entries(); entries.hasMoreElements();)
names.add(entries.nextElement().getName());
addName = addName.replace('\\', '/');
boolean exists = names.contains(addName) || names.contains(addName.replace('/', '\\'));
if (!overwrite && exists) throw new RuntimeException("JAR already has entry: " + addName);
if (!exists) {
names.add(addName);
Collections.sort(names);
}
if (names.remove("META-INF/MANIFEST.MF") || names.remove("META-INF\\MANIFEST.MF")) names.add(0, "META-INF/MANIFEST.MF");
for (String name : names) {
outJarStream.putNextEntry(new JarEntry(name.replace('\\', '/')));
if (name.replace('\\', '/').equals(addName))
outJarStream.write(bytes);
else
copyStream(inJarFile.getInputStream(inJarFile.getEntry(name)), outJarStream);
outJarStream.closeEntry();
}
outJarStream.close();
inJarFile.close();
}
/**
* Accessing Resources from a JAR
File
You can construct a URL object by using the
reference of a resource in a JAR file.
The JAR file URL syntax is
jar:<url>!/{entry}
The following URL refers to an images/logo.bmp
JAR entry in a test.jar file on www.java2s.com
using the HTTP protocol:
jar:http://www.java2s.com/test.jar!/images/logo.bmp
The following URL refers to an images/logo.bmp
JAR entry in a test.jar file on the local file system
in the c:\jarfiles\ directory using the file protocol:
jar:file:/c:/jarfiles/test.jar!/images/logo.bmp
To read the images/logo.bmp file from a JAR file
in the classpath, you can get an input stream
object using a class object as follows:
// Assuming that the Test class is in the CLASSPATH
Class cls = Test.class;
InputStream in = cls.getResourceAsStream( "/images/logo.bmp" )
You can also get a URL object for an entry in your
JAR file, which is in your classpath as follows:
URL url = cls.getResource( "/images/logo.bmp" );
*/
public static void createJAR(String jarFileName, String root) throws Exception {
Collection<File> lf = FileUtil.getFiles(root, false);
if (!root.endsWith("/")) {
root = root + "/";
}
Manifest manifest = getManifest();
Log.i("createJar", jarFileName);
FileOutputStream fos = new FileOutputStream(jarFileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
JarOutputStream jos = new JarOutputStream(bos, manifest);
jos.setLevel(Deflater.DEFAULT_COMPRESSION);
// ArrayList<File> lf = new ArrayList<File>(jarEntries.length);
// lf.addAll(Arrays.asList(jarEntries));
// Collections.sort(lf);
// File manif = new File(root + "META-INF/MANIFEST.MF");
// int idx = Collections.binarySearch(lf, manif);
// System.out.println(idx);
// System.out.println(lf.get(0));
// System.out.println(lf.get(idx));
// File f = lf.remove(0);
// lf.add(0, manif);
// lf.remove(idx);
// lf.add(idx, f);
// System.out.println(lf.get(0));
// System.out.println(lf.get(idx));
File[] toArray = lf.toArray(new File[lf.size()]);
for (File entryFile : toArray) {//lf
if (!entryFile.exists()) {
Log.e("Error", entryFile + " is not existed, continue next files");
continue;
}
String absolutePath = entryFile.getAbsolutePath().replaceAll("\\\\", "/");
String substring = absolutePath.substring(root.length());
Log.d("JarEntry", substring);
JarEntry je = new JarEntry(substring);
jos.putNextEntry(je);
copyFileToOutputStreamFlushNotClose(jos, entryFile);
jos.closeEntry();
}
jos.close();
// ZipFile zf = new ZipFile(jarFileName);
// Enumeration<? extends ZipEntry> entries = zf.entries();
// while (entries.hasMoreElements()) {
// System.out.println(entries.nextElement());
// }
// zf.close();
}