home
diamond Go Premium
Data Engineering Path  ·  PySpark

RDD - Read files (text , csv ..)

While parallelizing local memory collections is useful for testing, real-world big data workflows require reading datasets from external storage systemssuch as a local filesystem, Hadoop Distributed File System (HDFS), Amazon S3, or Azure Blob Storage.

This guide details the core methods for reading files into RDDs (sc.textFile and sc.wholeTextFiles) and provides complete code examples for parsing unstructured raw text, semi-structured CSV tables, and structured JSON logs.


1. Core Spark File-Reading Methods

Spark provides two main low-level methods in SparkContext for loading files into RDDs:

A. sc.textFile(path, minPartitions=None)

  • Behavior: Reads a text file line-by-line. Each line of the text file becomes a single element (string) in the resulting RDD.
  • Partitions: Spark splits the file across partitions. By default, it allocates one partition per 128MB block of the file, but you can override this by passing a custom minPartitions value.
  • Compression: Automatically detects and decompresses standard formats like .gz, .bz2, and .zip on the fly.

B. sc.wholeTextFiles(path, minPartitions=None)

  • Behavior: Reads a directory containing multiple small text files. It returns a Key-Value RDD where:
    • Key: The absolute path/URI of the file (string).
    • Value: The complete, entire text content of that specific file (string).
  • When to use: Highly optimized for directories containing hundreds of small log or configuration files where you need to process each file as a single record.

2. PySpark Code Examples

Setup Spark Session

from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("Day01 RDD Read Files") \
    .master("local[*]") \
    .getOrCreate()

sc = spark.sparkContext

A. Reading a Plain Text File (textFile)

Let's read a text file where each element in the RDD corresponds to one line of the file:

# 1. Read a local text file into an RDD
# (Assume a file named 'sample logs.txt' exists in the current directory)
logs_rdd = sc.textFile("sample_logs.txt")

# 2. Print RDD type
print("RDD Type:", type(logs_rdd))
# Output: RDD Type: <class 'pyspark.rdd.RDD'>

# 3. Fetch the first 3 lines of the file using take()
lines_preview = logs_rdd.take(3)
print("First 3 lines of file:")
for line in lines_preview:
    print(f"  Line: {line}")

B. Reading Multiple Files with Wildcards (*)

You can use standard directory globbing wildcards to read all text files matching a pattern into a single RDD:

# Read all files ending in '.log' from the logs directory
all_logs_rdd = sc.textFile("logs/*.log")

# Count total combined lines across all matching log files
total_lines = all_logs_rdd.count()
print(f"Total lines in all log files: {total_lines}")

C. Processing Directories of Small Files (wholeTextFiles)

Let's read an entire directory of small files and inspect the absolute paths along with the file contents:

# 1. Read directory as key-value pairs (FilePath, CompleteContent)
small_files_rdd = sc.wholeTextFiles("configs_directory/")

# 2. View the count of files read
print(f"Number of files loaded: {small_files_rdd.count()}")

# 3. Inspect the records
files_data = small_files_rdd.collect()
for file_path, file_content in files_data[:2]: # Show first 2 files
    print(f"
File Location: {file_path}")
    print(f"File Contents:
{file_content}")

D. Reading and Manually Parsing a CSV File

Because RDD is a low-level API, it does not automatically detect columns or headers of a CSV. We must read the file line-by-line and manually parse the fields:

Let's assume the CSV file dataset.csv contains:

id,name,age,city
1,Alice,28,New York
2,Bob,32,San Francisco
3,Charlie,22,Chicago
# 1. Load the raw text file
raw_csv_rdd = sc.textFile("dataset.csv")

# 2. Filter out the header row
header = raw_csv_rdd.first() # Get the very first line (the header)
data_rows_rdd = raw_csv_rdd.filter(lambda line: line != header)

# 3. Manually split each line by comma and map to a structured tuple: (ID, Name, Age, City)
def parse_csv_line(line):
    parts = line.split(",")
    # Convert types where necessary
    row_id = int(parts[0])
    name = parts[1]
    age = int(parts[2])
    city = parts[3]
    return (row_id, name, age, city)

parsed_rdd = data_rows_rdd.map(parse_csv_line)

# 4. View parsed results
print("Parsed CSV Rows:")
for row in parsed_rdd.collect():
    print(f"  Row: {row}")

# Expected Output:
# Parsed CSV Rows:
# Row: (1, 'Alice', 28, 'New York')
# Row: (2, 'Bob', 32, 'San Francisco')
# Row: (3, 'Charlie', 22, 'Chicago')

E. Reading and Parsing JSON Lines

To read standard JSON Lines files (where each line is a valid JSON object), we can use Python's built-in json module:

Let's assume data.json contains:

{"user": "Alice", "score": 95}
{"user": "Bob", "score": 88}
import json

# 1. Read JSON file line-by-line
raw_json_rdd = sc.textFile("data.json")

# 2. Use map to parse the JSON string into a Python dictionary
parsed_json_rdd = raw_json_rdd.map(lambda line: json.loads(line))

# 3. Extract specific values from the parsed dictionaries
user_scores_rdd = parsed_json_rdd.map(lambda obj: (obj["user"], obj["score"]))

print("Parsed JSON records:")
print(user_scores_rdd.collect())
# Output: [('Alice', 95), ('Bob', 88)]

Tip

Performance Recommendation: For reading structured formats like CSV, JSON, and especially Parquet, you should highly prefer Spark's high-level DataFrame API (e.g., spark.read.csv(), spark.read.json(), spark.read.parquet()). DataFrames automatically handle header filtering, type inference, schema enforcement, and compile to highly optimized execution plans!

Find this content helpful? ☕ Buy me a coffee

Entity Details

Create New Item

celebration
Enjoying the free content?

Create a free account to track your progress and save your place.

Create Free Account
help

Submit Technical Query

Have a question or run into an issue? Describe it below, upload an optional screenshot, and our engineering team will answer it!

image Attach image (optional)

Submit Feedback

build Free Developer Utility Free Tool
gavel

Privacy & Legal Disclaimer

1. Client-Side Browser Processing

All utility tools on DeepEngineerHub (including Image to PDF, Text Formatters, JSON Converters, and Encryptors) execute 100% locally within your client browser using WebAssembly and JavaScript. No uploaded images, text, or documents are transmitted, collected, or stored on remote servers.

2. Limitation of Liability ("As-Is" Provision)

Tools and services are provided free of charge for convenience and educational purposes "as-is" without warranties of any kind. DeepEngineerHub shall not be held liable for any data loss, formatting inconsistencies, or indirect damages resulting from tool usage.

3. Open Source & Third-Party Software

Certain utilities utilize open-source client libraries (such as jsPDF, Mermaid.js, Pyodide) licensed under MIT, Apache, or BSD open licenses. All intellectual property remains with their respective copyright holders.