当前位置: 首页 > 知识库问答 >
问题:

DataInputStream readLine()已弃用

宋涵衍
2023-03-14

我需要使用DataInputStream,因为我需要弃用的readLine()功能,我不知道输入文件的确切文件格式(即使用什么行尾),但也需要读取二进制编码的原语。

这与这个问题类似:

是否有一个类公开Java中的非缓冲readLine方法?

我的建议是用这样的东西

public class SaveDataInputStream extends DataInputStream {
  public SaveDataInputStream(InputStream in) {super(in);}
  public String readLineSave() throws IOException {
    // ???
  }
}

并使用DataInputStream类中可以找到的readLine()方法内容(这类似于所引用问题中接受的答案)。然而,我不完全理解为什么该方法被弃用,我更想知道它是否与我的代码相关。

javadoc说:这个方法不能正确地将字节转换为字符。

但这意味着什么?我应该担心吗?最坏的情况下会发生什么?是否有可能编写我自己的方法来解决这个问题(效率并不是一个真正的问题)?

提示:新的BufferedReader(新的InputStreamReader(...));不是正确答案...

共有2个答案

龙哲
2023-03-14

我不是100%确定,但我发现与BufferedReader相比,该方法工作不正确。readLine()。代码如下:

import java.io.*;

public class HelloWorld {
  public static void main(String[] args) throws Exception {
    String s = "喜\n";
    InputStream in = new ByteArrayInputStream(s.getBytes());
    DataInputStream d = new DataInputStream(in);
    System.out.println(d.readLine()); // prints å

    in = new ByteArrayInputStream(s.getBytes());
    BufferedReader br = new BufferedReader(new InputStreamReader(in));
    System.out.println(br.readLine()); // prints 喜
  }
}

基本上,DataInputStream似乎根本不处理多字节字符,因为它基本上在中处理char next=(char)。read();对于每个字符。

基本上,我认为为了正确读取多字节字符,您至少需要一个非常小的缓冲区。也就是说,您可能可以直接在InputStreamReader之上构建自定义方法,而不是BufferedReader,因为这样可以正确处理多字节字符。或者,如果您知道您总是要处理ascii,那么使用不推荐的方法可能是安全的。

编辑:还值得注意的是,即使是DataInputStream也会在内部缓冲,以便正确处理\r\n行结尾。至少在jdk7中,对\r的处理是:

          case '\r':
            int c2 = in.read();
            if ((c2 != '\n') && (c2 != -1)) {
                if (!(in instanceof PushbackInputStream)) {
                    in = new PushbackInputStream(in);
                }
                ((PushbackInputStream)in).unread(c2);
            }
            break loop;

因此,如果我们遇到像\ra这样的东西,a被未读回推回输入流,该流维护未读字节的内部缓冲区。

陆博易
2023-03-14

当他们说readLine()因为不能正确转换字符而被弃用时,他们的意思是不允许您指定字符编码,例如UTF-8对CP1252。这意味着使用一个字符编码写入的数据很可能会失败,如果读取一个默认为不同字符编码的系统。

那么,你需要担心吗?当然方法被弃用,以向开发人员提供警告,指出它可能在将来消失。也就是说,根据JavaDoc,readLine()在很久以前的JDK1.1中就被弃用了。

至于你不想因为缓冲而使用BufferedReader的观点,我会说不要使用它。使用扩展Reader的其他类之一,或者,如果你想达到这个极端,滚动你自己的类。没有什么能阻止您创建自己的名为DataInputReader的类,使用方法读取基元,并提供适当的readLine()实现来满足您的需求。

但是,如果您正在读取二进制编码的数据,我建议您根本不要使用读取器,而是坚持使用InputStream,这样您就可以读取原始字节并自己处理转换Readers的设计考虑到了字符编码的处理,因此在试图将二进制数据转换为字符串的前提下,它倾向于修改您正在阅读的内容。

 类似资料:
  • 问题内容: 今天,我决定将我的android应用程序从Java转换为Kotlin!:)但是,当我输入以下内容时,我感到非常惊讶: 然后Android Studio告诉我:“’getActionView(MenuItem!):View!’ 已弃用。Java中已弃用“ 因此,在问您解决方案之前,我先问谷歌解决方案是什么,我相信我找到了解决方案:“直接使用getActionView()”。 所以我像这样

  • 目前我正在开发一个带有三个菜单项的底部导航栏的应用程序。我曾使用来单击项目。但现在我面临的问题是该方法已贬值。 应用程序语言:Java 问题:“setOnNavigationItemSelectedListener(com.google.android.material.bottomnavigation.BottomNavigationView.OnNavigationItemSelectedLi

  • 由于API 27已弃用。对此最好的替代方案是什么? 在我的例子中,我知道需要使用之类的东西,但我不知道在我的代码中这需要去哪里。 我在班上得到了这些进口货: 但是 被划掉了。

  • 我一直在开发一个使用Google Drive API的Android应用程序。它最初是从这里的quickstart示例构建的。API调用的简化序列(此处未显示正确的错误处理)是: 它一直运行良好,我正准备发布我的应用程序。但是,在驱动器API更新之后,我突然收到一个警告 方法usingOAuth2(Context,String,String...)GoogleAccountCredential是不

  • Variable (已弃用) Variable 是早期添加到 RxSwift 的概念,通过 “setting” 和 “getting”, 他可以帮助我们从原先命令式的思维方式,过渡到响应式的思维方式。 但这只是我们一厢情愿的想法。许多开发者滥用 Variable,来构建 重度命令式 系统,而不是 Rx 的 声明式 系统。这对于新手很常见,并且他们无法意识到,这是代码的坏味道。所以在 RxSwift

  • 问题内容: 我正在3.6.0版中使用Hibernate,并且AnnotationConfiguration标记为已弃用。 这是我的HibernateUtil.java类中的行: 什么是AnnotationConfiguration的替代品? 问题答案: “所有功能已移至配置”:http : //docs.jboss.org/hibernate/core/3.6/javadocs/org/hiber

  • 问题内容: 我最近将我的项目的Jasper Reports库从 3.7.6 升级到了 6.0.0 。我终于可以进行Maven构建,并且报告工作得很好。但是, setParameter() 函数在两个发行版之间似乎已被弃用,并且我不确定如何重构我的代码以适应此问题。 不推荐使用的代码示例: 我浏览了SourceForge页面,可以看到它已被 ExporterInput , ExporterConfi

  • 今天,我试图设置,但我发现它不推荐使用。