2015-04-30 17 views
5

Java kursumun bir parçası olarak Huffman algoritması çalıştığı için bir "zip" yazarı ve okuyucusu yazdım.Okuyucuyu genişletmek "okumam" nasıl olur?

Benim sınıf Reader genişletir ve bir nesne Okuyucu r var.

input = new BufferedReader(new HuffmanReader(new FileReader("output.hff"))); 
String str = input.readLine(); 

Elbette, bunu açtıktan sonra, ben dosyaya yazdım sıkıştırılmış dize dönmelidir: benim ana yöntemde, ben bu satırları var. Ama dosyanın ilk satırını döndürür!

Benim okuma fonksiyonu:

public int read(char[] cbuf, int off, int len) throws IOException { 
    //... 
    r.read(buffer,0,8192) 
    //does the decompress process 
    String fnlStr = ... //The final result 
    cbuf = fnlStr.toCharArray(); 
    //close streams 
    return cbuf.length; 
} 

Benim ayıklama penceresi bunu gösterir:

HuffmanReader.read(char[], int, int) line: 23 
BufferedReader.fill() line: not available 
BufferedReader.readLine(boolean) line: not available  
BufferedReader.readLine() line: not available 
Run.main(String[]) line: 23 

Benim okuma işlevini iki kez çağırır. BufferReader'ın tekrar okuma işlevini çağırmasını nasıl durdurabilirim?

+0

1. 'read()' fonksiyonunuzda 'off' ve' len' olarak mı düşünüyorsunuz? 2. BufferedReader'a ihtiyacınız var mı (test yapamazsınız)? – xerx593

+1

'input''dan okuduğunuz tek yer, doğal olarak yalnızca bir satır okuyan input.readLine()' dır. 'Read' işlevinin hiç işe yaramadığını biraz şaşırdım, çünkü aslında içine geçen arabelleğe yazmıyorsunuz, 'cbuf' için yeni bir arabellek atamanız yeterli. – dddsnn

+0

Ayrıca, r.read() tarafından döndürülen sayıyı da kullanmazsınız. Bu kod muhtemelen işe yaramaz. – EJP

cevap

2

Sen yönteminden okumak gibi her zaman yaptığınız verileri döndürmez. read çağrıldığında Bunun yerine, arayan size aslında belleğin bir yığın adresidir dizi cbuf verir ve içine lenchar s yazma anlatır.

cbuf = fnlStr.toCharArray()'u yaptığınızda, bu adresin yerel kopyanızı başka bir adresle değiştirirsiniz, ancak yazmanız gereken belleği gerçekten değiştirmezsiniz. for döngüsünde verdiğiniz diziyi yinelemeli ve buna yazmalısınız ya da sonucu içeren başka bir arabellek oluşturduysanız System.arraycopy kullanın.

Ör aşağıdaki read yöntem her zaman "Test\n" okuyacaktır:

public int read(char[] cbuf, int off, int len) throws IOException { 
    char[] result = "Test\n".toCharArray(); 
    int numRead = Math.min(len, result.length); 
    System.arraycopy(result, 0, cbuf, off, numRead); 
    return numRead; 
} 

başlangıç ​​almalısınız sizin decompressed dizeyle "Test\n" literal değiştirilmesi. Elbette, hâlihazırda tüketmiş olduğunuz kaynağın ne kadarını yönetmeniz gerekecek.


Ve BufferedReader iki kez read çağrılmasına olarak

: bunu denir ne sıklıkta bakım gerekir. Verileri temel kaynağınızdan alınız, cbuf'a yazınız ve yazdığınız char sayısını yazınız. Okunacak bir şey kalmazsa, akımın sonuna sinyal vermek için -1 değerini döndürün (bu durumda BufferedReader, read'u aramayı durdurur).Bir kenara

, Reader InputStream is for binary data (sadece byte[] yerine char[] ile ve bir charset kullanmadan, temelde aynı şey) iken, karakter akışlarını okumak içindir. Sıkıştırılmış dosyalar ikili olduğundan, FileReader'nuzu FileInputStream'a geçirmek isteyebilirsiniz.

Bazı nedenlerden dolayı, kodladığınız karakter dizisinin, kod çözdüğünüzle aynı olmaması durumunda tuhaf hatalar hayal edebiliyorum. Ya da daha az çarpıcı bir şekilde, UTF-16'daki bir 16 bit kod biriminin UTF-8'de 3 8 bit kod birimine ihtiyacı varsa, düşündüğünüzden daha fazla alan kullanabilirsiniz.

+0

Çok teşekkür ederim! Bu benim sorunumdu. İyi çalışıyor! Okuyucu ile ilgili problemi biliyorum, bu alıştırma için sahip olduğumuz bir sınır. Teşekkür ederim. –

1

Yalnızca ilk satırı okuyoruz. Senin yöntem iki kez çağrıldığı düzeltmek için bir boole yapmak ve stilini şeyler yapmış sonra true ayarlamak, ayrıca

input = new BufferedReader(new HuffmanReader(new FileReader("output.hff"))); 
Arraylist<String> list = new ArrayList<String>(); 
String line; 

while ((line = reader.readLine()) != null) { 
    list.add(line); 
} 

Ve: gibi bir şey ilk bölümünü değiştirin. Daha sonra, bu yöntemin başlangıcında, boolean'ın doğru olup olmadığını kontrol edin. Öyleyse, yöntemden dönün, böylece tekrardan sonra bir şeyleri yürütmeyecek.

+0

Veya yöntemi bir kez arayın ;-) – EJP

+0

@ ImBatman64 Merhaba, daha önce boolean denedim ve işe yaramadı çünkü sonuçumu arabelleğe nasıl yazacağımı bilmiyorum. Bir dahaki sefere geldiğinde, bazı boşluklarla Dize str dizesine döner. Ana bölümü değiştiremiyorum - bu egzersizin bir parçası. BufferedReader sadece bir satır okumalı olmasına rağmen tekrar okumaya çalışıyor. –

+0

@RoeiJacobovich Yöntemi tam olarak nerede arıyorsunuz? – ImBatman64

İlgili konular