Как считать из файла double java

Обновлено: 04.07.2024

кажется, есть разные способы чтения и записи данных из файлов в Java.

Я хочу прочитать данные ASCII из файла. Каковы возможные пути и их различия?

ASCII-это текстовый файл, поэтому вы будете использовать читателей для чтения. Java также поддерживает чтение из двоичного файла с помощью InputStreams. Если считываемые файлы огромны, вы захотите использовать командой bufferedreader на FileReader для улучшения производительности.

пройти в этой статье о том, как использовать Reader

Я также рекомендую вам скачать и прочитать эту замечательную (пока бесплатно) забронировать называется Мышление На Java

В Java 7:

В Java 8:

мой любимый способ чтения небольшого файла-использовать BufferedReader и StringBuilder. Это очень просто и по существу (хотя и не особенно эффективно, но достаточно хорошо для большинства случаев):

некоторые указали, что после Java 7 Вы должны использовать try-with-resources (т. е. автоматическое закрытие) особенности:

когда я читаю строки, как это, я обычно хочу сделать некоторую обработку строк в строке в любом случае, поэтому я иду на это реализация.

хотя, если я хочу на самом деле просто прочитать файл в строку, я всегда использую Apache Commons IO С классом IOUtils.метод toString. Вы можете посмотреть на источник здесь:

и еще проще с Java 7:

самый простой способ-использовать Scanner класс в Java и объект FileReader. Простой пример:

Scanner имеет несколько методов для чтения в строках, числах и т. д. Дополнительную информацию об этом можно найти на странице документации Java.

например, чтение всего содержимого в String :

кроме того, если вам нужна конкретная кодировка вы можете использовать это вместо FileReader :

вот простое решение:

вот еще один способ сделать это без использования внешних библиотек:

Я должен был проверить разные способы. Я прокомментирую свои выводы, но, короче говоря, самый быстрый способ-использовать простой старый BufferedInputStream над FileInputStream. Если необходимо прочитать много файлов, то три потока сократят общее время выполнения примерно до половины, но добавление большего количества потоков будет постепенно снижать производительность, пока не займет в три раза больше времени для завершения двадцати потоков, чем только с одним потоком.

предполагается, что вы должны прочитать файл и сделать что-то значимое с его содержанием. В примерах здесь читаются строки из журнала и подсчитываются те, которые содержат значения, превышающие определенный порог. Поэтому я предполагаю, что однострочный Java 8 Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";")) - это не вариант.

Я тестировал на Java 1.8, Windows 7 и SSD и HDD дисках.

Я написал шесть различных реализаций:

rawParse: используйте BufferedInputStream над FileInputStream, а затем вырезать строки чтения байт за байтом. Это превзошло любой другой однопоточный подход, но это может быть очень неудобно для файлов, отличных от ASCII.

lineReaderParse: используйте BufferedReader над FileReader, читайте строку за строкой, разделяйте строки, вызывая строку.расщеплять.)( Это примерно на 20% медленнее, чем rawParse.

lineReaderParseParallel: это то же самое, что lineReaderParse, но он использует несколько потоков. Это самый быстрый вариант в целом случаи.

nioFilesParse: используйте java.НИО.файлы.Файлы.lines ()

nioAsyncParse: используйте асинхронный канал с обработчиком завершения и пулом потоков.

nioMemoryMappedParse: используйте файл, сопоставленный с памятью. Это действительно плохая идея, дающая время выполнения по крайней мере в три раза больше, чем любая другая реализация.

это среднее время для чтения 204 файлов по 4 МБ каждый на четырехъядерный i7 и SSD-накопитель. Файлы создаются на лету, чтобы избежать кэширования диска.

Я нашел разницу меньше, чем я ожидал, между запуском на SSD или жестком диске SSD примерно на 15% быстрее. Это может быть связано с тем, что файлы генерируются на нефрагментированном HDD, и они читаются последовательно, поэтому вращающийся диск может работать почти как SSD.

Я был удивлен низкой производительностью реализации nioAsyncParse. Любой Я реализовал что-то неправильно или многопоточная реализация с использованием NIO, а обработчик завершения выполняет то же самое (или даже хуже), что и однопоточная реализация с java.IO API. Кроме того, асинхронный синтаксический анализ с CompletionHandler намного длиннее в строках кода и сложнее реализовать правильно, чем прямая реализация на старых потоках.

теперь шесть реализаций, за которыми следует класс, содержащий их все, плюс параметризуемый метод main() это позволяет играть с количеством файлов, размером файла и степенью параллелизма. Обратите внимание, что размер файлов варьируется плюс минус 20%. Это позволяет избежать какого-либо эффекта из-за того, что все файлы одинаковы размер.

Репутация: нет
Всего: нет

Допустим программа должна работать с файлом-библиотекой, такого типа: double double string.
Т.е. например:
0.66 0.87 Cs-137
0.79 0.57 Cs-134
. и т.д.

Вопрос такое: как без анализа строки просто считать данные из такого файла?

Дело в том, я новичок в Java, а в C++ подобные вещи делал очень просто через оператор ">>". Таким образом не анализируя строку (это уже описано в операторной ф-ции ">>") просто считывал значения нужного типа. Есть подозрение что аналогичным образом можно действовать и в Java, но я пока не нашел подходящего способа.

Прошу подсказать как это правильно делать в Java с наименьшими затратами.

Leprechaun Software Developer

Репутация: 206
Всего: 534

Репутация: 47
Всего: 159

Вот код программы нашей:

Код

import java.io.FileInputStream;
import java.util.Scanner;

Вот результат её выполнения:

Цитата

int = 123
int = 456
string = Hello
int = 7890
int = 12345
string = Test

Добавлено @ 17:02
Оперэдыли.

нет времени думать - нужно писать КОД!

Leprechaun Software Developer

Репутация: 206
Всего: 534


Маленькое дополнение, я в своем примере не написал, и тут тоже не указанно, но потоки надо закрывать за собой.

Репутация: -1
Всего: нет

powerOn, добрый день.

Поддерживает ли Ваш вариант программы с использованием метода Scanner чтение арифметических операций?
Когда я ввёл в текстовом файле знаки арифметических операций, то стектрейс вывел следующее:

java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at NewClass.main(NewClass.java:13)

Leprechaun Software Developer

Репутация: 206
Всего: 534


Смотря что подразумевать под чтением арифметических операций. Если нужно прочитать сами знаки этих операций, то да поддерживает. Их надо читать через next(). А если надо провести вычисления по этим операциям, то тут уже нужно использовать скриптовые языки, типа BeanShell.

Репутация: -1
Всего: нет

нужно счиать сами знаки для начала..а потом провести вычисления по этим операциям, но для этого я хочу написать свой алгоритм. Не могли бы вы дать небольшой пример с методом next , чтобы было понятнее.
Спасибо.

Leprechaun Software Developer

Репутация: 206
Всего: 534

Код

import java.io.*;
import java.util.*;

Репутация: нет
Всего: нет


Сканер - это хорошая штука, только вот мне нужно прочитать данные из строк такого типа:
Цитата

1 54782 ИВАНОВ СЕРГЕЙ ПЕТРОВИЧ 446.43 100385

где 446.43 - число типа double.

Для чтения пробую использовать код:

При чтении значения v = sc.nextDouble(); получаю ошибку java.util.InputMismatchException (не совпадает тип). Когда число записано как 446,43 (с запятой вместе точки), то сканер воспринимает его как double. Как быть?

AA - Aussie Animal

Репутация: 21
Всего: 104

Kisja, Scanner использует текущую локаль для определения формата чисел. Поэтому вам нужно задать локаль, в которой вещественные числа через точку.
Попробуйте вот так:
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

[ Время генерации скрипта: 0.1503 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Ввод-вывод в Java. Классы FileInputStream, FileOutputStream, BufferedInputStream - 1

Привет! В сегодняшней лекции продолжим разговор о потоках ввода и вывода в Java, или сокращенно — Java I/O («input-output»). Это не первая лекция на данную тему, и далеко не последняя :) Так уж получилось, что Java как язык предоставляет много возможностей по работе с вводом-выводом. Классов, которые реализуют эту функциональность довольно много, поэтому мы разделили их на несколько лекций, чтобы ты поначалу не запутался :) В прошлых лекциях мы коснулись BufferedReader ’a, а также абстрактных классов InputStream & OutputStream и нескольких наследников. Сегодня рассмотрим 3 новых класса: FileInputStream , FileOutputStream и BufferedInputStream .

Класс FileOutputStream

Главное назначение класса FileOutputStream — запись байтов в файл. Ничего сложного :) FileOutputStream является одной из реализаций абстрактного класса OutputStream . В конструкторе объекты этого класса принимают либо путь к целевому файлу (в который и нужно записать байты), либо объект класса File . Рассмотрим оба примера: При создании объекта File мы указали в конструкторе путь, где он должен будет находиться. Создавать его заранее нет необходимости: если он не существует, программа создаст его сама. Можно обойтись и без создания лишнего объекта, и просто передать строку с адресом: Результат в обоих случаях будет одинаковым. Мы можем открыть наш файл и увидеть там: Однако есть здесь один нюанс. Попробуй запустить код из примера выше несколько раз подряд, а потом загляни в файл, и ответь на вопрос: сколько записанных в него строк ты видишь? Всего одну. Но ведь ты запускал код несколько раз. Однако при этом данные, оказывается, всякий раз перезаписывались, заменяя старые. Что делать, если нас это не устраивает, и требуется последовательная запись? Что если мы хотим записать наше приветствие в файл три раза подряд? Здесь все просто. Поскольку сам язык не может знать, какое именно поведение нам нужно в каждом случае, в конструктор FileOutputStream ты можешь передать дополнительный параметр — boolean append . Если его значение true, данные будут дозаписаны в конец файла. Если false (а по умолчанию это значение и есть false), старые данные будут стерты, а новые записаны. Давай проверим и запустим наш измененный код трижды: Результат в файле: Другое дело! Не забывай об этой особенности при использовании классов ввода-вывода. В свое время и мне приходилось часами сидеть над задачами, чтобы понять, куда деваются из файлов мои старые данные :) Ну и конечно, как и в случае с другими классами I/O, не забываем об освобождении ресурсов через метод close() .

Класс FileInputStream

Ввод-вывод в Java. Классы FileInputStream, FileOutputStream, BufferedInputStream - 2

У класса FileInputStream назначение противоположное — чтение байтов из файла. Так же как FileOutputStream наследует OutputStream , этот класс происходит от абстрактного класса InputStream . Запишем в наш текстовый « test.txt » несколько строк текста: Вот как будет выглядеть реализация чтения данных из файла при помощи FileInputStream : Мы считываем из файла по одному байту, преобразуем считанные байты в символы и выводим их в консоль. А вот и результат в консоли:

Класс BufferedInputStream

Думаю, учитывая знания из прошлых лекций, ты легко сможешь сказать, зачем нужен класс BufferedInputStream и какие преимущества у него есть по сравнению с FileInputStream :) Мы уже встречались с буферизированными потоками, поэтому попробуй предположить (или вспомнить), прежде чем продолжить чтение :) Буферизированные потоки нужны прежде всего для оптимизации ввода-вывода. Обращение к источнику данных, например, чтение из файла, — дорогостоящая в плане производительности операция. И каждый раз обращаться к файлу для чтения по одному байту расточительно. Поэтому BufferedInputStream считывает данные не по одному байту, а блоками и временно хранит их в специальном буфере. Это позволяет нам оптимизировать работу программы за счет того, что мы уменьшаем количество обращений к файлу. Давай посмотрим, как это выглядит: Здесь мы создали объект BufferedInputStream . Он принимает на вход объект InputStream или любого его наследника, так что предыдущий FileInputStream подойдет. В качестве дополнительного параметра он принимает размер буфера в байтах. Теперь благодаря этому данные будут считываться из файла не по одному байту, а по 200! Представь, насколько мы сократили количество обращений к файлу. Для сравнения производительности ты можешь взять какой-нибудь большой текстовый файл размером несколько мегабайт и сравнить, сколько займет его чтение и вывод в консоль в миллисекундах с использованием FileInputStream и BufferedInputStream . Вот оба варианта кода для примера: При чтении файла размером 1,5 Мб на моем компьютере FileInputStream выполнил работу за

3500 миллисекунд, а вот BufferedInputStream — за

1700 миллисекунд. Как видишь, буферизированный поток оптимизировал работу программы в 2 раза! :) Мы еще продолжим изучать классы ввода-вывода — до встречи!

В этом уроке мы будем использовать методы Files.lines (), Files.ReadString (), Files.ReadAllBytes() и классы FileReader, BufferedReader и Scanner для чтения файла в строку на Java с примерами.

Вступление

В этом уроке мы будем считывать файл в строку на Java. Существует несколько способов чтения текстового содержимого файла.

Вот список всех классов и методов, которые мы рассмотрим:

  • Файлы.строки()
  • Файлы.Строка чтения()
  • Файлы.ReadAllBytes()
  • Устройство для чтения файлов
  • Буферизатор
  • Сканер

Файлы.строки()

Класс Files содержит статические методы для работы с файлами и каталогами. Полезным методом является lines () , который возвращает поток строк: Поток<Строка> . Из этого потока можно получить строки, содержащиеся в файле.

Метод принимает Путь к файлу, который мы хотели бы прочитать, с необязательной кодировкой . Мы будем использовать синтаксис try-with-resources для автоматизации очистки и закрытия:

Поскольку метод возвращает Поток , мы используем его для каждого() метода для перебора строк со ссылкой на метод для краткости.

Вместо печати каждой строки для добавления строк можно использовать StringBuilder :

С помощью StringBuilder весь файл может быть представлен в одной Строке (переменная содержимое выше). Перед выполнением таких итераций важно учитывать длину входного файла.

Если файл не слишком велик, можно поместить его в строку, хотя, если он размером в сотни мегабайт, это не так мудро.

Файлы.Строка чтения()

Начиная с Java 11, класс Files познакомил нас с методом ReadString () , который принимает Путь к файлу, а также Кодировку .

В отличие от Files.lines() , он возвращает Строку напрямую, а не Поток объект:

Файлы.ReadAllBytes()

Этот метод также принимает Путь к файлу, который мы хотели бы прочитать:

Теперь массив байт содержит всю информацию из input.txt файл. Самый простой способ преобразовать его в строку-поместить их в конструктор с необязательной кодировкой :

Примечание: Такие решения, как чтение всех байтов, подходят только в тех случаях, когда мы имеем дело с файлами небольших размеров. Это не способствует повышению производительности, и нет особого смысла хранить большие файлы в памяти программы.

Сканер

Поскольку мы работаем со строками, мы хотели бы использовать методы, возвращающие строки. Сканер имеет next() и nextLine() именно для этого. Оба метода возвращают объекты типа String . Первый используется для чтения произвольных строк, в то время как второй анализирует и возвращает целые строки.

Если каждая строка содержит нужное количество данных, то следующая строка() является идеальным выбором. Если в файле есть важная информация, которая разбита на более мелкие фрагменты, но не обязательно на строки (или файл содержит, скажем, одну строку), то next() может быть лучшим вариантом.

Мы используем цикл while до тех пор, пока sc содержит больше элементов. Если бы мы не проверили с помощью hasNext() , sc выдал бы Исключение NoSuchElementException , если мы попытаемся получить доступ к элементу после последнего.

Идея использования методов hasNext() и next() исходит из интерфейса Итератора , поскольку Сканер реализует его внутренне.

Устройство для чтения файлов

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

Файл FileReader используется для чтения файлов. Он предлагает методы read() и read(char []) , которые возвращают один символ и несколько символов соответственно. Кроме того, он принимает Файл или Строку в конструктор.

Считыватель файлов.чтение(символ[])

Давайте откроем файл с помощью FileReader и прочитаем его содержимое:

Метод read() принимает последовательность символов (в которой мы храним прочитанные символы), начальную и конечную точки того, что мы хотели бы прочитать. В частности, мы решили прочитать не более 256 символов. Если input.txt имеет больше, мы будем читать только 256 символов. Если в нем меньше, возвращаются читаемые символы.

Возвращаемое значение, хранящееся внутри целого числа n , может быть использовано для проверки того, сколько символов метод на самом деле прочитал. В случае, если достигнут конец потока, метод возвращает -1 .

Поскольку метод заполняет символ[] , мы можем преобразовать его в Строку . Аналогичный результат можно получить с помощью String.valueOf(char[]) .

Читатель файлов.чтение()

Метод read() без char[] считывает по одному символу за раз. Мы захотим просмотреть содержимое и прочитать каждый символ самостоятельно:

Здесь мы проверяем, не является ли прочитанный символ -1 , что указывало на то, что для чтения больше не осталось символов. Если нет, мы добавим() его в StringBuilder и, наконец, преобразуем его в Строку .

Примечание: Оба read() и read(char[]) считанные байты, преобразуйте их в символы и возвращайте их по одному . Это неэффективно и должно выполняться с помощью буферизации , когда это возможно.

Буферизатор

Рекомендуется обернуть любой потенциально дорогостоящий считыватель в BufferedReader для повышения производительности, поскольку буферизация символов обеспечивает более эффективное чтение входного текста.

Давайте создадим экземпляр BufferedReader :

На данный момент у нас есть объект bufferedreader, готовый для чтения содержимого из input.txt . В этом примере мы будем читать файл построчно, хотя BufferedReader поддерживает чтение отдельных символов по отдельности, а также нескольких символов в массив.

Давайте используем этот экземпляр BufferedReader для чтения файла и сохранения его содержимого, строка за строкой, в строку:

Еще раз, мы используем StringBuilder для сбора всех строк. Чтобы разделить каждую строку, мы добавляем нулевой терминатор ( \n ) между ними. Наконец, мы закрываем ручей.

Вывод

В этой статье мы рассмотрели некоторые распространенные методы чтения файлов в строки на Java. Существует множество вариантов, но большинство из них имеют схожий основной принцип: укажите путь к файлу, прочитайте содержимое в структуру данных (например, char[] или строку); затем выполните некоторую окончательную обработку, чтобы собрать все содержимое файла соответствующим образом.

Читайте также: