Худшая часть - то, что, когда Вы пишете новый код, его твердое, чтобы знать, если Вы случайно представили больше предупреждений, с тех пор существуют так многие, Вы просто игнорируете их так или иначе.
проблема с очисткой их всех, то, что это занимает время, что Вы можете или не можете иметь. Но да, обычно необходимо очистить столько, сколько Вы можете.
CodeSource src = MyClass.class.getProtectionDomain().getCodeSource();
if (src != null) {
URL jar = src.getLocation();
ZipInputStream zip = new ZipInputStream(jar.openStream());
while(true) {
ZipEntry e = zip.getNextEntry();
if (e == null)
break;
String name = e.getName();
if (name.startsWith("path/to/your/dir/")) {
/* Do something with this entry. */
...
}
}
}
else {
/* Fail... */
}
Обратите внимание, что в Java 7 вы можете создать FileSystem
из файла JAR (zip), а затем использовать механизмы просмотра каталогов и фильтрации NIO для поиска в нем. Это упростило бы написание кода, обрабатывающего JAR-файлы и "развернутые" каталоги.
Имея фактический файл JAR, вы можете перечислить его содержимое с помощью JarFile. записи ()
. Однако вам нужно будет знать местоположение файла JAR - вы не можете просто попросить загрузчик классов перечислить все, что он может получить.
Вы должны иметь возможность определить местоположение файла JAR на основе возвращенного URL из ThisClassName.class.getResource ("ThisClassName.class")
, но это может быть немного неудобно.
Файл jar - это просто файл zip со структурированным манифестом. Вы можете открыть файл jar с помощью обычных инструментов java zip и таким образом просканировать содержимое файла, раздуть потоки и т. Д. Затем использовать это в вызове getResourceAsStream, и все должно получиться очень громоздко.
EDIT / после уточнения
] Мне потребовалась минута, чтобы вспомнить все мелочи, и я уверен, что есть более чистые способы сделать это, но я хотел убедиться, что я не сумасшедший. В моем проекте image.jpg - это файл в некоторой части основного файла jar. Я получаю загрузчик классов основного класса (SomeClass - это точка входа) и использую его для обнаружения ресурса image.jpg. Затем немного магии потока, чтобы поместить его в эту штуку ImageInputStream, и все в порядке.
InputStream inputStream = SomeClass.class.getClassLoader().getResourceAsStream("image.jpg");
JPEGImageReaderSpi imageReaderSpi = new JPEGImageReaderSpi();
ImageReader ir = imageReaderSpi.createReaderInstance();
ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
ir.setInput(iis);
....
ir.read(0); //will hand us a buffered image
Итак, я предполагаю, что моя основная проблема будет в том, как узнать имя jar-файла, в котором находится мой основной класс.
Предполагая, что ваш проект упакован в Jar (не обязательно верно! ), вы можете использовать ClassLoader.getResource () или findResource () с именем класса (за которым следует .class), чтобы получить банку, содержащую данный класс. Вам нужно будет проанализировать имя jar-файла из возвращаемого URL (не так сложно), что я оставлю как упражнение для читателя: -)
Обязательно проверьте случай, когда класс не является частью банки.
Вот метод, который я написал для «запуска всех JUnits в пакете». Вы сможете адаптировать его под свои нужды.
private static void findClassesInJar(List<String> classFiles, String path) throws IOException {
final String[] parts = path.split("\\Q.jar\\\\E");
if (parts.length == 2) {
String jarFilename = parts[0] + ".jar";
String relativePath = parts[1].replace(File.separatorChar, '/');
JarFile jarFile = new JarFile(jarFilename);
final Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
final String entryName = entry.getName();
if (entryName.startsWith(relativePath)) {
classFiles.add(entryName.replace('/', File.separatorChar));
}
}
}
}
Изменить: Ах, в этом случае вам может понадобиться и этот фрагмент (тот же вариант использования :))
private static File findClassesDir(Class<?> clazz) {
try {
String path = clazz.getProtectionDomain().getCodeSource().getLocation().getFile();
final String codeSourcePath = URLDecoder.decode(path, "UTF-8");
final String thisClassPath = new File(codeSourcePath, clazz.getPackage().getName().repalce('.', File.separatorChar));
} catch (UnsupportedEncodingException e) {
throw new AssertionError("impossible", e);
}
}
ответ Эриксона работал отлично:
Вот рабочий код.
CodeSource src = MyClass.class.getProtectionDomain().getCodeSource();
List<String> list = new ArrayList<String>();
if( src != null ) {
URL jar = src.getLocation();
ZipInputStream zip = new ZipInputStream( jar.openStream());
ZipEntry ze = null;
while( ( ze = zip.getNextEntry() ) != null ) {
String entryName = ze.getName();
if( entryName.startsWith("images") && entryName.endsWith(".png") ) {
list.add( entryName );
}
}
}
webimages = list.toArray( new String[ list.size() ] );
И я только что изменил свой метод загрузки с этого:
File[] webimages = ...
BufferedImage image = ImageIO.read(this.getClass().getResource(webimages[nextIndex].getName() ));
На это:
String [] webimages = ...
BufferedImage image = ImageIO.read(this.getClass().getResource(webimages[nextIndex]));
Есть две очень полезные утилиты, обе называются JarScan:
См. Также этот вопрос: JarScan, сканировать все Файлы JAR во всех подпапках для определенного класса