আমার জাভা ব্যবহার করে প্রায় 5-6 জিবি লাইনের একটি বড় টেক্সট ফাইল পড়তে হবে।
আমি কীভাবে এটি দ্রুত করতে পারি?
আমার জাভা ব্যবহার করে প্রায় 5-6 জিবি লাইনের একটি বড় টেক্সট ফাইল পড়তে হবে।
আমি কীভাবে এটি দ্রুত করতে পারি?
উত্তর:
একটি সাধারণ প্যাটার্ন ব্যবহার করা হয়
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// process the line.
}
}
আপনি যদি ধরে নেন কোনও চরিত্রের এনকোডিং নেই তবে আপনি ডেটাটি দ্রুত পড়তে পারেন। উদাহরণস্বরূপ ASCII-7 তবে এতে খুব বেশি পার্থক্য হবে না। এটি অত্যন্ত সম্ভবত যে আপনি ডেটা দিয়ে যা করেন তা অনেক বেশি সময় নেয়।
সম্পাদনা: ব্যবহার করার জন্য একটি কম সাধারণ প্যাটার্ন যা line
ফাঁসের সুযোগ এড়ায়।
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
for(String line; (line = br.readLine()) != null; ) {
// process the line.
}
// line is not visible here.
}
আপডেট: জাভা 8 এ আপনি করতে পারেন
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
}
দ্রষ্টব্য: আপনি # ক্লোজ পদ্ধতিটি কল করা হয়েছে কিনা তা নিশ্চিত করার জন্য আপনাকে স্ট্রিমটি একটি চেষ্টা করে রিসোর্স ব্লকে স্থাপন করতে হবে, অন্যথায় অন্তর্নিহিত ফাইল হ্যান্ডেলটি কখনই বন্ধ হয় না যতক্ষণ না জিসি এটি পরে না করে।
for(String line = br.readLine(); line != null; line = br.readLine())
বিটিডব্লু কেন নয় , জাভা 8-এ আপনি করতে পারেন try( Stream<String> lines = Files.lines(...) ){ for( String line : (Iterable<String>) lines::iterator ) { ... } }
যা ঘৃণা করা শক্ত নয়।
এই ব্লগ দেখুন:
বাফার আকার নির্দিষ্ট করা যেতে পারে, বা ডিফল্ট আকার ব্যবহার করা যেতে পারে। বেশিরভাগ উদ্দেশ্যে ডিফল্ট যথেষ্ট বড়।
// Open the file
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
fstream.close();
DataInputStream
, এবং ভুল প্রবাহ বন্ধ আছে। জাভা টিউটোরিয়ালের সাথে কোনওরকম ভুল নেই, এবং এটির মতো নির্বিচারে তৃতীয় পক্ষের ইন্টারনেট আবর্জনা উদ্ধৃত করার প্রয়োজন নেই।
একবার জাভা 8 বের হয়ে গেলে (মার্চ 2014) আপনি স্ট্রিম ব্যবহার করতে সক্ষম হবেন:
try (Stream<String> lines = Files.lines(Paths.get(filename), Charset.defaultCharset())) {
lines.forEachOrdered(line -> process(line));
}
ফাইলের সমস্ত লাইন মুদ্রণ করা হচ্ছে:
try (Stream<String> lines = Files.lines(file, Charset.defaultCharset())) {
lines.forEachOrdered(System.out::println);
}
StandardCharsets.UTF_8
, ব্যবহার করুন Stream<String>
এবং ব্যবহার এড়িয়ে চলুন forEach()
এবং বিশেষত forEachOrdered()
যদি কোনও কারণ না থাকে।
forEach(this::process)
, কিন্তু এটা কুশ্রী পায় যদি আপনি ভিতরে lambdas যেমন কোডের ব্লক লিখতে forEach()
।
forEachOrdered
কার্যকর করতে আপনার প্রয়োজন । সচেতন থাকুন যে সেক্ষেত্রে আপনি স্ট্রিমটিকে সমান্তরাল করতে পারবেন না, যদিও আমি খুঁজে পেয়েছি যে ফাইলটিতে কয়েক হাজার লাইন না থাকলে সমান্তরালতা চালু হয় না।
প্রাক-জাভা 7. এর জন্য সম্পূর্ণ ত্রুটি পরিচালনা ও সমর্থনকারী চরসেটের বিশদকরণ সহ একটি নমুনা এখানে Java. জাভা With এর সাহায্যে আপনি ট্রান্স-রিসোর্স সিনট্যাক্স ব্যবহার করতে পারেন, যা কোড ক্লিনার করে।
আপনি যদি কেবল ডিফল্ট চরসেটটি চান তবে আপনি ইনপুটস্ট্রিমটি এড়িয়ে যেতে পারেন এবং ফাইলআরডার ব্যবহার করতে পারেন।
InputStream ins = null; // raw byte-stream
Reader r = null; // cooked reader
BufferedReader br = null; // buffered for readLine()
try {
String s;
ins = new FileInputStream("textfile.txt");
r = new InputStreamReader(ins, "UTF-8"); // leave charset out for default
br = new BufferedReader(r);
while ((s = br.readLine()) != null) {
System.out.println(s);
}
}
catch (Exception e)
{
System.err.println(e.getMessage()); // handle exception
}
finally {
if (br != null) { try { br.close(); } catch(Throwable t) { /* ensure close happens */ } }
if (r != null) { try { r.close(); } catch(Throwable t) { /* ensure close happens */ } }
if (ins != null) { try { ins.close(); } catch(Throwable t) { /* ensure close happens */ } }
}
এখানে পুরো ত্রুটি পরিচালনা সহ গ্রুভি সংস্করণ রয়েছে:
File f = new File("textfile.txt");
f.withReader("UTF-8") { br ->
br.eachLine { line ->
println line;
}
}
ByteArrayInputStream
একটি স্ট্রিং দ্বারা প্রতিপালিত বৃহৎ টেক্সট ফাইল পড়া কি আছে আক্ষরিক?
জাভা 8 এ, আপনি করতে পারেন:
try (Stream<String> lines = Files.lines (file, StandardCharsets.UTF_8))
{
for (String line : (Iterable<String>) lines::iterator)
{
;
}
}
কিছু দ্রষ্টব্য: ফিরে আসা স্ট্রিমটি Files.lines
(বেশিরভাগ স্ট্রিমের বিপরীতে) বন্ধ করা দরকার। এখানে উল্লিখিত কারণে আমি ব্যবহার এড়াচ্ছি forEach()
। অদ্ভুত কোডটি (Iterable<String>) lines::iterator
একটি স্ট্রিমকে একটি আইটেবলের পক্ষে ফেলে।
Iterable
এই কোডটি কার্যকরভাবে নির্ধারণ করা কুৎসিত । এটি (Iterable<String>)
কাজ করার জন্য একটি কাস্ট (যেমন ) প্রয়োজন)
for(String line : (Iterable<String>) lines.skip(1)::iterator)
Stream
, বৈশিষ্ট্য ব্যবহার Files.newBufferedReader
পরিবর্তে Files.lines
এবং বারবার আহ্বান readLine()
পর্যন্ত null
পরিবর্তে নির্মান ব্যবহার করার মত (Iterable<String>) lines::iterator
অনেক সহজ হবে বলে মনে হয় ...
আপনি যা করতে পারেন তা হ'ল স্ক্যানারটি ব্যবহার করে পুরো পাঠ্যটি স্ক্যান করুন এবং পাঠ্য লাইনটি লাইনে যেতে হবে। অবশ্যই আপনার নিম্নলিখিতগুলি আমদানি করা উচিত:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public static void readText throws FileNotFoundException {
Scanner scan = new Scanner(new File("samplefilename.txt"));
while(scan.hasNextLine()){
String line = scan.nextLine();
//Here you can manipulate the string the way you want
}
}
স্ক্যানার মূলত সমস্ত পাঠ্য স্ক্যান করে। লুপটি পুরো পাঠ্যের মধ্য দিয়ে যেতে ব্যবহার করা হয়।
.hasNextLine()
ফাংশন একটি বুলিয়ান যে সত্য ফেরৎ যদি টেক্সট এখনও আরও লাইন হয়। .nextLine()
ফাংশন আপনি একটি স্ট্রিং যা আপনি পরে আপনি যেভাবে চান ব্যবহার করতে পারেন যেমন একটি সম্পূর্ণ লাইন দেয়। System.out.println(line)
পাঠ্য মুদ্রণের চেষ্টা করুন ।
পার্শ্ব দ্রষ্টব্য: .txt ফাইল টাইপ পাঠ্য।
BufferedReader.readLine()
এবং তিনি সেরা পারফরম্যান্স পদ্ধতিটি চেয়েছিলেন।
ফাইলরেডার আপনাকে এনকোডিং নির্দিষ্ট করতে দেয় না, তার InputStreamReader
পরিবর্তে যদি আপনাকে এটি নির্দিষ্ট করে প্রয়োজন হয় তা ব্যবহার করুন:
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "Cp1252"));
String line;
while ((line = br.readLine()) != null) {
// process the line.
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
আপনি যদি উইন্ডোজ থেকে এই ফাইলটি আমদানি করেন তবে এটিতে এএনএসআই এনকোডিং থাকতে পারে (Cp1252), সুতরাং আপনাকে এনকোডিং নির্দিষ্ট করতে হবে।
আমি জাভাতে একটি ফাইল পড়ার জন্য 10 টি বিভিন্ন উপায়ে নথিভুক্ত ও পরীক্ষিত করেছি এবং তারপরে 1KB থেকে 1GB পর্যন্ত টেস্ট ফাইলগুলিতে পড়ার মাধ্যমে একে অপরের বিরুদ্ধে চালিয়েছি। 1GB পরীক্ষার ফাইল পড়ার জন্য এখানে দ্রুত 3 ফাইল পড়ার পদ্ধতি রয়েছে।
নোট করুন যে পারফরম্যান্স টেস্টগুলি চালানোর সময় আমি কনসোলে কিছুই আউটপুট পাইনি যেহেতু সত্যই পরীক্ষাটি ধীর হয়ে যাবে। আমি কেবল কাঁচা পড়ার গতি পরীক্ষা করতে চেয়েছিলাম।
1) java.nio.file.Files.readAllBytes ()
জাভা 7, 8, 9. এ পরীক্ষিত এটি সামগ্রিকভাবে দ্রুততম পদ্ধতি ছিল। একটি 1 জিবি ফাইল পড়ার ধারাবাহিকভাবে ঠিক 1 সেকেন্ডের নীচে ছিল।
import java.io..File;
import java.io.IOException;
import java.nio.file.Files;
public class ReadFile_Files_ReadAllBytes {
public static void main(String [] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
File file = new File(fileName);
byte [] fileBytes = Files.readAllBytes(file.toPath());
char singleChar;
for(byte b : fileBytes) {
singleChar = (char) b;
System.out.print(singleChar);
}
}
}
2) java.nio.file.Files.lines ()
এটি জাভা 8 এবং 9 এ সফলভাবে পরীক্ষা করা হয়েছিল তবে লাম্বদা এক্সপ্রেশনগুলির সমর্থন না থাকার কারণে এটি জাভা 7 তে কাজ করবে না। এটি একটি ১ জিবি ফাইলে পড়তে প্রায় ৩.৫ সেকেন্ড সময় নিয়েছিল যা বড় ফাইলগুলি পড়া পর্যন্ত এটি দ্বিতীয় স্থানে রেখেছিল।
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;
public class ReadFile_Files_Lines {
public static void main(String[] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
File file = new File(fileName);
try (Stream linesStream = Files.lines(file.toPath())) {
linesStream.forEach(line -> {
System.out.println(line);
});
}
}
}
3) বাফারডারিডার
জাভা 7, 8, 9 এ কাজ করার জন্য পরীক্ষিত হয়েছিল 1 জিবি পরীক্ষার ফাইলে পড়তে এটি প্রায় 4.5 সেকেন্ড সময় নিয়েছিল।
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile_BufferedReader_ReadLine {
public static void main(String [] args) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
FileReader fileReader = new FileReader(fileName);
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
}
আপনি এখানে 10 টি ফাইল পঠনের জন্য সম্পূর্ণ র্যাঙ্কিং সন্ধান করতে পারেন ।
System.out.print/println()
এখানে সময় হয়; আপনি ধরে নিচ্ছেন যে ফাইলটি আপনার প্রথম দুটি ক্ষেত্রে মেমরির সাথে খাপ খায়।
জাভা 7 এ:
String folderPath = "C:/folderOfMyFile";
Path path = Paths.get(folderPath, "myFileName.csv"); //or any text file eg.: txt, bat, etc
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(path , charset)) {
while ((line = reader.readLine()) != null ) {
//separate all csv fields into string array
String[] lineVariables = line.split(",");
}
} catch (IOException e) {
System.err.println(e);
}
StandardCharsets.UTF_8
চেক করা ব্যতিক্রম এড়ানোর জন্য ব্যবহার করুনCharset.forName("UTF-8")
জাভা 8-তে, ব্যবহারের বিকল্পও রয়েছে Files.lines()
। যদি আপনার ইনপুট উত্সটি কোনও ফাইল না হয় তবে একটি Reader
বা এর মতো আরও বিমূর্ত কিছু হয় তবে InputStream
আপনি এস পদ্ধতির মাধ্যমে লাইনগুলি প্রবাহিত করতে পারেন ।BufferedReader
lines()
উদাহরণ স্বরূপ:
try (BufferedReader reader = new BufferedReader(...)) {
reader.lines().forEach(line -> processLine(line));
}
processLine()
দ্বারা পড়া প্রতিটি ইনপুট লাইনের জন্য কল করবে BufferedReader
।
জাভা 8 সহ একটি ফাইল পড়ার জন্য
package com.java.java8;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
/**
* The Class ReadLargeFile.
*
* @author Ankit Sood Apr 20, 2017
*/
public class ReadLargeFile {
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(String[] args) {
try {
Stream<String> stream = Files.lines(Paths.get("C:\\Users\\System\\Desktop\\demoData.txt"));
stream.forEach(System.out::println);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
আপনি স্ক্যানার ক্লাস ব্যবহার করতে পারেন
Scanner sc=new Scanner(file);
sc.nextLine();
Scanner
করা ভাল, তবে এই উত্তরটিতে এটি সঠিকভাবে ব্যবহারের জন্য সম্পূর্ণ কোড অন্তর্ভুক্ত নয়।
BufferedReader.readLine()
এটি বেশ কয়েকগুণ দ্রুত। আপনি যদি অন্যথায় মনে করেন তবে আপনার কারণগুলি সরবরাহ করুন।
আপনার readLine()
পদ্ধতিটি ব্যবহার করতে হবে class BufferedReader
। এই শ্রেণি থেকে একটি নতুন অবজেক্ট তৈরি করুন এবং তার উপর এই পদ্ধতিটি পরিচালনা করুন এবং এটিকে একটি স্ট্রিংয়ে সংরক্ষণ করুন।
এটি অর্জনের সুস্পষ্ট উপায়,
উদাহরণ স্বরূপ:
আপনার যদি dataFile.txt
আপনার বর্তমান ডিরেক্টরিতে থাকে
import java.io.*;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class readByLine
{
public readByLine() throws FileNotFoundException
{
Scanner linReader = new Scanner(new File("dataFile.txt"));
while (linReader.hasNext())
{
String line = linReader.nextLine();
System.out.println(line);
}
linReader.close();
}
public static void main(String args[]) throws FileNotFoundException
{
new readByLine();
}
}
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
}
System.getProperty("os.name").equals("Linux")
==
!
BufferedReader br;
FileInputStream fin;
try {
fin = new FileInputStream(fileName);
br = new BufferedReader(new InputStreamReader(fin));
/*Path pathToFile = Paths.get(fileName);
br = Files.newBufferedReader(pathToFile,StandardCharsets.US_ASCII);*/
String line = br.readLine();
while (line != null) {
String[] attributes = line.split(",");
Movie movie = createMovie(attributes);
movies.add(movie);
line = br.readLine();
}
fin.close();
br.close();
} catch (FileNotFoundException e) {
System.out.println("Your Message");
} catch (IOException e) {
System.out.println("Your Message");
}
এটা আমার জন্য কাজ করে. আশা করি এটি আপনাকেও সহায়তা করবে।
আপনি আরও সুনির্দিষ্টভাবে করতে স্ট্রিম ব্যবহার করতে পারেন:
Files.lines(Paths.get("input.txt")).forEach(s -> stringBuffer.append(s);
আমি সাধারণত পড়ার রুটিন সোজা করেই করি:
void readResource(InputStream source) throws IOException {
BufferedReader stream = null;
try {
stream = new BufferedReader(new InputStreamReader(source));
while (true) {
String line = stream.readLine();
if(line == null) {
break;
}
//process line
System.out.println(line)
}
} finally {
closeQuiet(stream);
}
}
static void closeQuiet(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ignore) {
}
}
}
আপনি এই কোডটি ব্যবহার করতে পারেন:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class ReadTextFile {
public static void main(String[] args) throws IOException {
try {
File f = new File("src/com/data.txt");
BufferedReader b = new BufferedReader(new FileReader(f));
String readLine = "";
System.out.println("Reading file using Buffered Reader");
while ((readLine = b.readLine()) != null) {
System.out.println(readLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Org.apache.commons.io প্যাকেজটি ব্যবহার করে এটি আরও কার্যকারিতা দিয়েছে, বিশেষত লিগ্যাসি কোড যা জাভা 6 এবং নীচে ব্যবহার করে।
কম ব্যতিক্রম হ্যান্ডলিং এবং আরও দরকারী পদ্ধতি সহ জাভা 7 এর একটি আরও ভাল API রয়েছে:
LineIterator lineIterator = null;
try {
lineIterator = FileUtils.lineIterator(new File("/home/username/m.log"), "windows-1256"); // The second parameter is optionnal
while (lineIterator.hasNext()) {
String currentLine = lineIterator.next();
// Some operation
}
}
finally {
LineIterator.closeQuietly(lineIterator);
}
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
আপনি অ্যাপাচি কমন্স আইও ব্যবহার করতে পারেন :
File file = new File("/home/user/file.txt");
try {
List<String> lines = FileUtils.readLines(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileUtils.readLines(file)
হতাশ পদ্ধতি। অতিরিক্তভাবে, পদ্ধতিটি আহ্বান জানায় IOUtils.readLines
, যা একটি বাফার্ডারিডার এবং অ্যারেলিস্ট ব্যবহার করে। এটি একটি লাইন বাই লাইন পদ্ধতি নয় এবং এটি অবশ্যই কোনও এক জিবি পড়ার জন্য ব্যবহারিক হবে না।