2012-09-24 9 views
6

W Servlet, buduję bardzo dużą ilość treści HTML w StringBuilder, który na końcu musi być zapisany w PrintWriter odpowiedzi. Aby użyć PrintWriter, należy najpierw wywołać metodę ToString() StringBuilder, aby uzyskać zawartość jako String. Ale to niepotrzebnie powiela zawartość. Czy istnieje jakiś sposób bezpośredniego zapisu z StringBuilder, ponieważ już trzyma zawartość?Napisz StringBuilder do Writer, bez toString()

PrintWriter może akceptować CharSequence, ale dokumentacja stwierdza, że ​​nazywa to CharSequence toString(), więc to naprawdę nie pomaga.

Jedyny jasny sposób, jaki widzę, polega na użyciu metody charAt (i) StringBuilder, aby uzyskać i napisać jedną postać na raz, ale czy to byłaby poprawa?

+2

Ulepszenie jest względne. Jeśli twoim celem jest zmniejszenie zużycia pamięci, to tak, to byłaby poprawa. Powinieneś sprawdzić, czy jest wolniejszy. Nie zdziwiłbym się, gdyby - ze względu na buforowanie strumienia wyjściowego - kara wykonania nie była wcale taka duża. –

Odpowiedz

7

Alternatywnie można upuścić StringBuilder i użyć StringWriter i PrintWriter.

+0

Potrzebuję wziąć zawartość HTML i napisać ją do PrintWriter w Servlet, która jest uzyskiwana przez wywołanie metody getWriter() HttpServletResponse. Nie widzę sposobu na połączenie tego z StringWriter. – worpet

2

Mogłeś po prostu napisać do PrintWriter w pierwszej kolejności zamiast StringBuilder ...

Korzystanie charAt pewno nie pomoże. Dałoby to bardzo słabą wydajność, aby zrobić to w ten sposób. Jeśli chcesz naprawdę chcesz kontynuować w tym kierunku, możesz może użyć metody StringBuilder.subString(start,end). Ta metoda pozwoli na odczytanie na przykład 1000 znaków naraz i wydrukowanie go na PrintWriter ...

+0

'StringBuilder.substring()' przydzieli nowy łańcuch za każdym razem, gdy go wywołasz. Mimo że całkowita ilość przydzielonej pamięci będzie mniejsza, to narzucony będzie dużo narzut. Pomyślałbym, że używanie funkcji charAt() nie będzie takie złe, ponieważ prawdopodobnie PrintWriter z Servleta jest i tak buforowany. –

2

Klasa StringBuilder przechowuje napis w wewnętrznej tablicy znaków. Problem polega na tym, że ta tablica znaków nie jest dostępna.

Proponowane rozwiązania:

1) Można stworzyć nową klasę rozciągający ObjectOutputStream, gdzie można zastąpić metodę writeObjectOverride(Object obj). Następnie wystarczy serializować instancję StringBuilder, w której skonstruowano dokument HTML. Twoja przesłonięta metoda writeObjectOverride(Object obj) zostanie wywołana z wewnętrzną tablicą znaków Stringbuilder, która jest częścią procesu serializacji, i voila: masz odwołanie do wewnętrznej tablicy znaków konstruktora String, to Twoja, aby napisać ją do PrintWriter w Servlet output ... Uwaga: Twoja metoda będzie wywoływana wiele razy, oczywiście możesz pominąć te, które przekazują ci coś innego niż pożądana tablica znaków.

2) Można użyć klasy CharBuffer zamiast StringBuilder, która ma metodę array() zwracającą tablicę wewnętrzną. CharBuffer nie mieć tyle append (lub put) działalność jako StringBuilder, więc będzie to wymagało przedłużenia tych trochę (w zależności od tego, co trzeba dokładnie) ...

3) można napisać własną implementację StringBuilder, a raczej to, czego używasz z niego. W ten sposób uzyskasz dostęp do obiektu (na przykład tablicy znaków), w którym przechowujesz zmontowany tekst ...

+0

Nie jestem pewien, czy rozwiązanie 1 zadziała, ponieważ aby użyć writeObjectOverride, należy przepisać większość logiki serializacji, ponieważ jeden parametr konstruktora ObjectOutputStream wyłącza wywołanie writeObjectOverride. to znaczy, że nie jest przeznaczony do użycia w ten sposób. Ponadto nie ma innych metod, które można wywołać w ramach obiektu writeObjectOverride, aby obsłużyć zwykły przypadek. Możesz użyć reflexion, ale menedżer bezpieczeństwa może stanąć na twojej drodze. – cquezel