字节流与Java中的字符流

时间:2017-10-22 13:45:28

标签: java stream java-io bytestream

我正在研究Java中的I / O类。我知道有两种重要的流类型:字节流和字符流。但是......我试图用字节流读取和写入文本文件并且它有效。这是代码:

    File klasor = new File("C:\\Java");
    if(!klasor.exists()) klasor.mkdirs();

    File kaynakDosya = new File("C:\\Java\\kaynak.txt");
    if(!kaynakDosya.exists()) kaynakDosya.createNewFile();

    File hedefDosya = new File("C:\\Java\\hedef.txt");
    if(!hedefDosya.exists()) hedefDosya.createNewFile();

    FileInputStream kaynak = new FileInputStream(kaynakDosya);
    FileOutputStream hedef = new FileOutputStream(hedefDosya);

    int c;
    while((c = kaynak.read()) != -1) {
        hedef.write(c);
    }

    if(kaynak != null) {
        kaynak.close();
    }

    if(hedef != null) {
        hedef.close();
    }

然后我对字符流做了同样的事情:

    File klasor = new File("C:\\Java");
    if(!klasor.exists()) klasor.mkdirs();

    File kaynakDosya = new File("C:\\Java\\kaynak.txt");
    if(!kaynakDosya.exists()) kaynakDosya.createNewFile();

    File hedefDosya = new File("C:\\Java\\hedef.txt");
    if(!hedefDosya.exists()) hedefDosya.createNewFile();

    FileReader kaynak = new FileReader(kaynakDosya);
    FileWriter hedef = new FileWriter(hedefDosya);

    int c;
    while((c = kaynak.read()) != -1) {
        hedef.write(c);
    }

    if(kaynak != null) {
        kaynak.close();
    }

    if(hedef != null) {
        hedef.close();
    }

这两个产生了相同的结果。所以,我想知道,为什么我不应该在这里使用字节流而是字符流? (我已经在stackoverflow上阅读了一些文章和相关问题,他们这么说)我知道字符流会逐个字符地读取它,但是这给了我什么优势呢?或者如果我使用字节流读取字符会出现什么问题?我希望我的问题很清楚。我会很感激实例。

3 个答案:

答案 0 :(得分:1)

java.io.FileInputStream javadoc声明:

  

FileInputStream用于读取原始字节流,例如   图像数据。要读取字符流,请考虑使用   的FileReader。

java.io.FileOutputStream javadoc陈述了类似的内容:

  

FileOutputStream用于写入原始字节流,例如   图像数据。要编写字符流,请考虑使用   FileWriter的。

FileInputStream/FileOutputStreamFileReader/FileWriter之间的主要区别之一是第一个提供操作字节的方法,而后者提供操作字符的方法。

在您的示例中,当您将文件内容复制到另一个文件时,操纵charbyte并没有太大区别。
在您的情况下,FileInputStreamBufferedInputStream似乎更合适。

但是如果你使用一个流来读/写String个实例中的字符, 使用FileReader/FileWriter可以简化事情,使事情更清晰 此外,您还可以将FileReader/FileWriter包装到BufferedReader/BufferedWriter中,并从字符,数组和行的有效读/写中受益。

 BufferedWriter writer = new BufferedWriter(new FileWriter("myfile"));
 writer.append(oneString);
 writer.append(oneStringBuffer);
 writer.newLine();

 BufferedReader reader = new BufferedReader(new FileReader("myfile"));
 String currentLine = reader.readLine();

答案 1 :(得分:1)

只有当流中的所有字符都可以用单个字节表示时,将字符写入面向字节的输出流(或从面向字节的输入流中读取字符)将产生与使用面向字符的流相同的结果在你的平台的默认编码中(通常是UTF-8,但它可能是其他东西)。要对此进行测试,请尝试包含需要多个字节来表示的文件(例如希腊语,西里尔语或阿拉伯语字符)。使用面向字节的流,这些将不起作用。使用面向字符的流,只要两个流都使用支持这些字符的编码(例如UTF-8)并且输入文件存储在用于输入流的编码中,就会保留字符。

请注意,面向字节的代码实际上并未对此进行测试,因为它只是逐字节地复制文件。一切看起来都有效,但是如果你试图读取实际的字符(比如,将它们与代码中的实际文本进行比较,就会失败。要测试这个,要创建一个文件(比方说,UTF-8编码),西里尔文本“Привет!”。然后在代码中,尝试使用面向字节的输入流将该文本读入String并测试它是否实际包含您期望的使用

System.out.println("Success: " + "Привет!".equals(input));

答案 2 :(得分:-1)

            import java.io.FileInputStream;
            import java.io.FileNotFoundException;
            import java.io.FileOutputStream;
            import java.io.IOException;
            public class Principale {
            public static void main(String[] args) {
            try(
            FileInputStream in = new FileInputStream("textfile.txt");
            FileOutputStream out = new FileOutputStream("new.txt");
   // for Characters streams
 // FileReader in = new FileReader("textfile.txt");
 // FileWriter out = new FileWriter("new.txt");

    //// for pictures
    //FileInputStream in = new FileInputStream("flower.jpeg");
    //FileOutputStream out = new FileOutputStream("flowernew.jpeg");
                ){
                    int c;
                    while((c = in.read()) != -1) {
                        out.write(c);
                        }   
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }