getResourceAsStream()
yönteminin farkındayım, ancak dosyayı okuyan ayrıştırıcıda bir sorun var, tüm yapı bir FileInputStream()
beklemek için uygulandı ve getResourceAsStream()
, dönüştürülemeyen bir girdi akışı döndürüyor. Bu durum için kolay bir "düzeltme" var mı?FileInputStream ile bir jardedeki txt dosyasına nasıl erişebilirim?
cevap
bir JAR dosyası içinde bulunan bir kaynak, bir dosya değil kendisi olduğunu ve bir FileInputStream
kullanılarak okunamaz. Kesinlikle bir FileInputStream
gerektiren bir kod varsa, getResourceAsStream()
kullanarak verileri ayıklamanız, geçici bir dosyaya kopyalamanız ve sonra bu geçici dosya için kodunuza bir FileInputStream
iletmeniz gerekir. Tabii
gelecekte, InputStream
gibi şeyler somut uygulamalarını beklemek kod yazmak asla, her zaman pişman olacaksın.
sizin ayrıştırma yalnızca FileInputStream çalışır inanıyoruz ama gerçek durum olmasa
inputStream ve o ayrıştırıcı
2 seçenek
kullanım adaptör desen kullanmalıdır yok bir CustomFileInputStream oluşturmak ve daha CustomFileInputStream
- 012 getResourceAsStream veri aktarımı ilgili yöntemleri üzerine yazmak Geçenlerde aynı sorunu yaşamıştır
Daha iyi bir çözüm, InputStream öğesini saran bir FileInputStream yazılır. İşte kullandığımız sınıf,
public class VirtualFileInputStream extends FileInputStream {
private InputStream stream;
public VirtualFileInputStream(InputStream stream) {
super(FileDescriptor.in); // This will never be used
this.stream = stream;
}
public int available() throws IOException {
throw new IllegalStateException("Unimplemented method called");
}
public void close() throws IOException {
stream.close();
}
public boolean equals(Object obj) {
return stream.equals(obj);
}
public FileChannel getChannel() {
throw new IllegalStateException("Unimplemented method called");
}
public int hashCode() {
return stream.hashCode();
}
public void mark(int readlimit) {
stream.mark(readlimit);
}
public boolean markSupported() {
return stream.markSupported();
}
public int read() throws IOException {
return stream.read();
}
public int read(byte[] b, int off, int len) throws IOException {
return stream.read(b, off, len);
}
public int read(byte[] b) throws IOException {
return stream.read(b);
}
public void reset() throws IOException {
stream.reset();
}
public long skip(long n) throws IOException {
return stream.skip(n);
}
public String toString() {
return stream.toString();
}
}
+1 ama ben sahte şeyler ihtiyacını vurgulamak için FakeFileInputStream diyeceğim :) ve somut FileInputStream uygulamasını kullanmamaya teşvik ediyorum. – helios
Kullandığımız sınıf, bu nedenle arabirime değil, uygulamanın kodlanmasına iyi bir fikirdir. – Powerlord
Giriş akışlarını uygulamalarına dökmemelisiniz. Boru ve filtreleri uygulamak için düşünülmektedir. Bu, bir (dosya) inputsrteam bir dosyadan okur, başka bir sıkıştırmayı (GZipI.S.S), başka bir kopuk çizgisi (bufferedI.S.), Başka ... vb. Dolayısıyla, programınız bir bayt akışı, bir girdi akışını bekler (herhangi bir I.S.) ve ardından bazı uygulamalarını sağlar. Akışı bir diğeriyle birleştirmek isterseniz: yeni GZipInputStream (yeni FileInputStream (yol)). – helios