GVKun编程网logo

等同于InputStream或Reader的Files.readAllLines()?(等同于的英文短语)

8

本篇文章给大家谈谈等同于InputStream或Reader的Files.readAllLines,以及?的知识点,同时本文还将给你拓展android–BufferedInputStream或File

本篇文章给大家谈谈等同于InputStream或Reader的Files.readAllLines,以及的知识点,同时本文还将给你拓展android – BufferedInputStream或FileInputStream IOException、bufferedinputstream FileInputStream inputstream的比较、c# – 需要帮助理解Microsoft对File.ReadLines和File.ReadAllLines的解释、DataInputStream.read()与DataInputStream.readFully()等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

等同于InputStream或Reader的Files.readAllLines()?(等同于的英文短语)

等同于InputStream或Reader的Files.readAllLines()?(等同于的英文短语)

我有一个通过以下方法读入列表的文件:

List<String> doc = java.nio.file.Files.readAllLines(new File("/path/to/src/resources/citylist.csv").toPath(), StandardCharsets.UTF_8);

是否有任何不错的(单行)Java 7/8 /
nio2方法可以在可执行Jar内的文件中实现相同的功能(大概必须使用InputStream读取)?也许是一种通过类加载器打开InputStream的方法,然后以某种方式将其强制/转换/包装为Path对象?还是包含与File.readAllLines(…)等效的InputStream或Reader的一些新子类?

我知道我 可以 用半页代码或通过某些外部库以传统方式完成此操作…但是在我这样做之前,我想确保Java的最新版本不能“立即使用” ”。

答案1

小编典典

An InputStream代表字节流。这些字节不一定形成可以逐行读取的(文本)内容。

如果您知道InputStream可以将解释为文本,则可以将其包装在中InputStreamReader并用于BufferedReader#lines()逐行使用它。

try (InputStream resource = Example.class.getResourceAsStream("resource")) {  List<String> doc =      new BufferedReader(new InputStreamReader(resource,          StandardCharsets.UTF_8)).lines().collect(Collectors.toList());}

android – BufferedInputStream或FileInputStream IOException

android – BufferedInputStream或FileInputStream IOException

我刚刚发布了一个Android应用程序,它解析本地文件并对数据进行一些处理.
几天前,我的一位客户报告了一个错误,每次他试图处理他的文件时应用程序崩溃.

这是他发给我的错误日志:

java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:300)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: lock == null
    at java.io.Reader.<init>(Reader.java:64)
    at java.io.InputStreamReader.<init>(InputStreamReader.java:120)

与此相关的代码是这样的:

// EDIT 1: Following greenapps comment I will put a more realistic version of this 
// method (The first version was invented because I wanted to be breaf)
public void selectFile()
{
    List<File> files = getDocsToParse();
    this.listview.setAdapter(this.myadapter);
    this.listview.setonItemClickListener(new OnItemClickListener()
    {
        ...
        @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        parseFile(files.get(position));
                }
        ...
    }
    this.myadapter.addFiles(files);
}

public static List<File> getDocsToParse() {
    File sdcard = Environment.getExternalStorageDirectory();
    File subdir = new File(sdcard, "MyAppFolder/Files/");
    // EDIT 2: I'm using  subdir.mkdirs(); because I want to 
    // create MyAppFolder/Files/ folders the first time the user use the app. 
    // Is this not correct? Should I create these folders any other way? 
    if (!subdir.exists()) {
        subdir.mkdirs();
    }
    File files[] = subdir.listFiles();
    List<File> filterFiles = new ArrayList<File>();
    for (int i = 0; i < files.length; i++) {
        File file = files[i];
        filterFiles.add(file);
    }
    return filterFiles;
}

public void parseFile(File filetoParse)
{
    long totalSize = 0;
    InputStream is = null;
    try {
            totalSize = filetoParse.length();
            is = new BufferedInputStream(new FileInputStream(filetoParse));
    } catch (IOException e) {
        e.printstacktrace();
    }
    BufferedReader reader = null;
    reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
    String line = "";
    StringTokenizer st = null;
    try {
        while ((line = reader.readLine()) != null) {
           // Here I parse the file
        }
    } catch (IOException e) {
        e.printstacktrace();
    }
}

崩溃的线是这一行:

reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));

我知道这是因为“是”是空的,我应该抓住这个案例,以避免应用程序崩溃(我将在我的下一个版本中修复此问题).

编辑3:你是对的,greenapps,我会在使用之前检查是否为null,在其他情况下我不会使用它.

我知道“is”是null,因为有一个IOException这样做:

 totalSize = filetoParse.length();
    is = new BufferedInputStream(new FileInputStream(filetoParse));

编辑4:当然,如果这给了我一个IOEXception,我将不得不改变我的代码,使一个完全不同的东西.

我无法在Internet上找到原因,因此这两行代码可能会抛出IOException.

认为filetoParse没问题,或者至少不是null,因为我将这个“文件”列表传递给适配器,用files.get(i).getName()显示它们的文件名,并正确显示名称.

我必须补充说,要处理的文件非常大并且具有敏感的个人数据,因此用户无法将其发送给我,因此我可以使用它进行测试.

没有我的文件给我这个错误,没有有问题的文件,我很难跟踪问题所以我不得不猜测.知道什么原因会导致这个错误吗?

非常感谢和亲切的问候!

编辑5:遵循ctarabusi建议我已将我的parseFile方法更改为:

public void parseFile(File filetoParse)
{
    long totalSize = 0;
    InputStream is = null;
    try {
            totalSize = filetoParse.length();
            is = new BufferedInputStream(new FileInputStream(filetoParse));
            BufferedReader reader = null;
            reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
            String line = "";
            StringTokenizer st = null;
            while ((line = reader.readLine()) != null) {
               // Here I parse the file
            }
    } catch (IOException e) {
          Toast.makeText(getApplicationContext(), "Error parsing file", Toast.LENGTH_LONG).show();
        e.printstacktrace();
    } finally {
        if(is != null)
        {
            try
            {
                is.close();
            }
            catch (IOException e)
            {
                Log.e("", e.getMessage(), e);
            }
        }
    }
}

我的测试再次正常工作,但是用户告诉我他看到了“Error parsing file”消息,所以它还没有失败.

我还能检查什么?

解决方法:

可能是您的问题是您没有关闭输入流.
文件描述符和流是有限的资源,完成它们后释放它们非常重要.

通常在finally块中完成,如:

InputStream inputStream = null;
try 
{
    ... use your input stream
}
catch (IOException e)
{
    Log.e(TAG, e.getMessage(), e);
}
finally
{
    if (inputStream != null)
    {
        try
        {
            inputStream.close();
        }
        catch (IOException e)
        {
            Log.e(TAG, e.getMessage(), e);
        }
    }
}

bufferedinputstream FileInputStream inputstream的比较

bufferedinputstream FileInputStream inputstream的比较

BufferedInputStream类相比InputStream类,提高了输入效率,增加了输入缓冲区的功能

 

不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低

带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多

 

InputStream流是指将字节序列从外设或外存传递到应用程序的流
BufferedInputStream流是指读取数据时,数据首先保存进入缓冲区,其后的操作直接在缓冲区中完成。

 

继承关系是这样的:
Java.lang.Object
     Java.io.InputStrean
          Java.io.FilterInputStream
                Java.io.BufferedInputStream

 

FileInputStream是字节流,BufferedInputStream是字节缓冲流,使用BufferedInputStream读资源比FileInputStream读取资源的效率高(BufferedInputStream的read方法会读取尽可能多的字节),且FileInputStream对象的read方法会出现阻塞;

 

BufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。

当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。

BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。

c# – 需要帮助理解Microsoft对File.ReadLines和File.ReadAllLines的解释

c# – 需要帮助理解Microsoft对File.ReadLines和File.ReadAllLines的解释

根据Microsoft对ReadLines和ReadAllLines方法的解释,当您使用ReadLines时,您可以在返回整个集合之前开始枚举字符串集合.使用ReadAllLines时,必须等待返回整个字符串数组才能访问该数组.因此,当您使用非常大的文件时,ReadLines可以更高效.

当他们说:

1 – “当您使用ReadLines时,您可以在返回整个集合之前开始枚举字符串集合.”
如果编写下面的代码行,那么这不意味着ReadLines方法执行结束并且返回整个集合&存储在变量filedata中?

IEnumerable<String> filedata = File.ReadLines(fileWithPath)

2 – “当您使用ReadAllLines时,必须等待返回整个字符串数组才能访问数组”.这是否意味着,在下面的代码片段中,如果读取一个大文件,那么如果在读取文件后立即使用数组变量hugeFileData将不会拥有所有数据?

string[] hugeFileData = File.ReadAllLines(path)
string i = hugeFileData[hugeFileData.length-1];

3 – “当您使用非常大的文件时,ReadLines可以更高效”.如果是这样,那么在读取大文件时,以下代码是否有效?我相信第二行和第三行下面的代码会读取文件两次,如果我错了,请纠正我.

string fileWithPath = "some large sized file path";
string lastLine = File.ReadLines(fileWithPath).Last();
int totalLines = File.ReadLines(fileWithPath).Count();

在上面的代码片段中两次在同一文件上调用ReadLines的原因是,当我尝试下面的代码时,我在下面的代码片段的第3行上得到了一个异常“无法从已关闭的TextReader中读取”.

IEnumerable<String> filedata = File.ReadLines(fileWithPath);
string lastLine = filedata.Last();
int totalLines = filedata.Count();

解决方法

ReadLines和ReadAllLines之间的区别很容易通过代码来说明.

如果你这样写:

foreach (var line in File.ReadLines(filename))
{
    Console.WriteLine(line);
}

发生的事情类似于:

using (var reader = new StreamReader(filename))
{
    while (!reader.EndOfStream)
    {
        var line = reader.ReadLine();
        Console.WriteLine(line);
    }
}

生成的实际代码稍微复杂一些(ReadLines返回一个枚举器,其MoveNext方法读取并返回每一行),但从外部来看,行为类似.

这种行为的关键是deferred execution,你应该很好地理解这一点,以便充分利用LINQ.所以你的第一个问题的答案是“不”.对ReadLines的所有调用都是打开文件并返回枚举器.在您要求之前,它不会读取第一行.

请注意,代码可以在第二行被读取之前输出第一行.此外,您一次只能使用一行内存.

ReadAllLines有很多不同的行为.当你写:

foreach (var line in File.ReadAllLines(filename))
{
    Console.WriteLine(line);
}

实际发生的事情更像是这样:

List<string> lines = new List<string>();
using (var reader = new StreamReader(filename))
{
    while (!reader.EndOfStream)
    {
        var line = reader.ReadLine();
        lines.Add(line);
    }
}
foreach (var line in lines)
{
    Console.WriteLine(line);
}

这里,程序必须先将整个文件加载到内存中,然后才能输出第一行.

你使用哪一个取决于你想做什么.如果您只需要逐行访问该文件,那么ReadLines通常是更好的选择 – 特别是对于大文件.但是如果你想随机访问行或者你将多次读取文件,那么ReadAllLines可能会更好.但是,请记住,ReadAllLines要求您有足够的内存来容纳整个文件.

在第三个问题中,您展示了此代码,该代码在最后一行产生了异常:

IEnumerable<String> filedata = File.ReadLines(fileWithPath);
string lastLine = filedata.Last();
int totalLines = filedata.Count();

这里发生的是第一行返回了一个枚举器.第二行代码枚举整个序列(即读到文件的末尾),以便它可以找到最后一行.枚举器看到它在文件末尾并关闭了相关的阅读器.最后一行代码再次尝试枚举该文件,但该文件已经关闭. ReadLines返回的枚举器中没有“重置到文件的开头”功能.

DataInputStream.read()与DataInputStream.readFully()

DataInputStream.read()与DataInputStream.readFully()

我正在制作一个简单的TCP / IP套接字应用

这样做之间有什么不同:

DataInputStream in = new DataInputStream(clientSocket.getInputStream());

byte[] buffer = new byte[100];
in.readFully(buffer);

与这样做:

DataInputStream in = new DataInputStream(clientSocket.getInputStream());

byte[] buffer = new byte[100];
in.read(buffer);

我看了看文档,它们具有完全相同的描述。readFully()并且read()
因此我可以假设它是一回事吗?

今天的关于等同于InputStream或Reader的Files.readAllLines的分享已经结束,谢谢您的关注,如果想了解更多关于android – BufferedInputStream或FileInputStream IOException、bufferedinputstream FileInputStream inputstream的比较、c# – 需要帮助理解Microsoft对File.ReadLines和File.ReadAllLines的解释、DataInputStream.read()与DataInputStream.readFully()的相关知识,请在本站进行查询。

本文标签: