Viết chuỗi vào luồng đầu ra


139

Tôi có một số trình nghe đầu ra đang triển khai OutputStream. Nó có thể là một bản in PrintStream cho thiết bị xuất chuẩn hoặc vào một tệp, hoặc nó có thể được ghi vào bộ nhớ hoặc bất kỳ đích đầu ra nào khác; do đó, tôi đã chỉ định OutputStream làm đối số (một) trong phương thức.

Bây giờ, tôi đã nhận được Chuỗi. Cách tốt nhất để viết vào luồng ở đây là gì?

Tôi có nên sử dụng Writer.write (message.getBytes ()) không? Tôi có thể cung cấp cho nó byte, nhưng nếu luồng đích là luồng ký tự thì nó có tự động chuyển đổi không?

Tôi có cần sử dụng một số luồng cầu ở đây không?


2
Tôi không chắc nhưng điều này nghe có vẻ như bạn đang cố gắng phát minh lại bánh xe ở đây, bạn đã xem qua API cơ sở Java, cũng như API IO của Commons chưa?
posdef

Câu trả lời:


149

Luồng ( InputStreamOutputStream) chuyển dữ liệu nhị phân . Nếu bạn muốn viết một chuỗi thành một luồng, trước tiên bạn phải chuyển đổi nó thành byte hoặc nói cách khác là mã hóa nó. Bạn có thể thực hiện thủ công (như bạn đề xuất) bằng cách sử dụng String.getBytes(Charset)phương thức, nhưng bạn nên tránh String.getBytes()phương thức đó, vì sử dụng mã hóa mặc định của JVM, không thể dự đoán một cách đáng tin cậy theo cách di động.

Tuy nhiên, cách thông thường để ghi dữ liệu ký tự vào một luồng là bọc luồng trong một Writer, (thường là a PrintWriter), đó là chuyển đổi cho bạn khi bạn gọi phương thức write(String)(hoặc print(String)) của nó . Trình bao bọc tương ứng cho InputStreams là Reader .

PrintStreamlà một OutputStreamtriển khai đặc biệt theo nghĩa là nó cũng chứa các phương thức tự động mã hóa chuỗi (nó sử dụng một trình ghi bên trong). Nhưng nó vẫn là một dòng. Bạn có thể bọc luồng của mình một cách an toàn cho bất kỳ nhà văn nào, bất kể đó là một PrintStreamhoặc một số triển khai luồng khác. Không có nguy cơ mã hóa kép.

Ví dụ về PrintWriter với OutputStream:

try (PrintWriter p = new PrintWriter(new FileOutputStream("output-text.txt", true))) {
    p.println("Hello");
} catch (FileNotFoundException e1) {
    e1.printStackTrace();
}

3
Vì vậy, sử dụng PrintWritercũng giống như sử dụng String.getBytes(). Nó sử dụng bất kỳ mã hóa ngẫu nhiên nào xảy ra là mặc định của JVM. Vì vậy, nó chỉ hoạt động nếu bạn may mắn.
Christoffer Hammarström

106

OutputStream ghi byte, String cung cấp ký tự. Bạn cần xác định Bộ ký tự để mã hóa chuỗi thành byte []:

outputStream.write(string.getBytes(Charset.forName("UTF-8")));

Thay đổi UTF-8một bộ ký tự của sự lựa chọn của bạn.


3
Nối với dòng sau. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Sahil Patel

32

Bạn có thể tạo một gói PrintStream xung quanh OutputStream của bạn và sau đó chỉ cần gọi nó là print (String):

final OutputStream os = new FileOutputStream("/tmp/out");
final PrintStream printStream = new PrintStream(os);
printStream.print("String");
printStream.close();

2
Bộ ký tự nào được PrintStream sử dụng để chuyển đổi thành byte?
Dean Hiller

20

Theo thiết kế, nó được thực hiện theo cách này:

OutputStream out = ...;
try (Writer w = new OutputStreamWriter(out, "UTF-8")) {
    w.write("Hello, World!");
} // or w.close(); //close will auto-flush

3
Lưu ý rằng w.close()sẽ đóng cửa outlà tốt.
Franklin Yu

12

Bao bọc OutputStream của bạn với PrintWriter và sử dụng các phương thức in trên lớp đó. Họ nhận một Chuỗi và thực hiện công việc cho bạn.


9

Bạn có thể sử dụng Apache Commons IO :

try (OutputStream outputStream = ...) {
    IOUtils.write("data", outputStream, "UTF-8");
}

IOUtils.write(String data, OutputStream output, Charset encoding)được triển khai như output.write(data.getBytes(Charsets.toCharset(encoding)))vậy, vì vậy có thể nếu một chuỗi được mã hóa không thể vừa với một mảng byte
Šarūnas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.